{ "cells": [ { "cell_type": "markdown", "id": "9f5d9871", "metadata": {}, "source": [ "# Tutorial 3 - Constrained Minimization\n", "\n", "This tutorial demonstrates how to perform constrained minimization for optical system design using Diffinytrace. It covers:\n", "\n", "- **Custom Material Definition**: Shows how to define a custom lens material with a wavelength-dependent refractive index.\n", "- **Setting Bounds**: Explains how to set bounds on lens surface curvatures and the central thickness of lenses by specifying bounds on the relevant parameters and transformations.\n", "- **System Construction**: Builds a sequential optical system with a light source, two lenses, and a detector, each with appropriate bounds.\n", "- **Viewing Bounds**: Provides code to inspect all currently defined bounds for system parameters.\n", "- **Nonlinear Constraints**: Demonstrates how to define nonlinear constraints using the `LEQZero` class, such as limiting the detector position.\n", "- **Minimization Routine**: Runs a constrained minimization using a merit function and the SLSQP optimizer.\n" ] }, { "cell_type": "code", "execution_count": 1, "id": "0ffc1cfd", "metadata": {}, "outputs": [], "source": [ "import sys\n", "import os\n", "import gc\n", "import tqdm\n", "sys.path.insert(0, os.path.abspath(\"..\"))\n", "device = \"cuda:0\"\n", "results_folder = \"results/\"\n", "results_folder += \"lens_export/\"\n", "try:\n", " os.mkdir(results_folder)\n", "except:\n", " pass" ] }, { "cell_type": "code", "execution_count": 2, "id": "acd8878b", "metadata": {}, "outputs": [], "source": [ "import diffinytrace as dit\n", "from diffinytrace.constraints import LEQZero\n", "import torch\n", "\n", "source_aper_r = 20.\n", "lens_aperture_r = 22.\n", "det_aper_r = 30.\n" ] }, { "cell_type": "markdown", "id": "bab66396", "metadata": {}, "source": [ "To define a custom lens material one just needs to intialize the RefractiveIndex class with a wavelength dependent refractive index" ] }, { "cell_type": "code", "execution_count": 3, "id": "28b4833d", "metadata": {}, "outputs": [], "source": [ "BaSF = dit.RefractiveIndex(\\\n", " lambda x:(1+1.65554268/(1-0.0104485644/x**2)+\\\n", " 0.17131977/(1-0.0499394756/x**2)+\\\n", " 1.33664448/(1-118.961472/x**2))**.5,\\\n", " [0.365,2.5])\n" ] }, { "cell_type": "markdown", "id": "450b70c4", "metadata": {}, "source": [ "Diffiny trace supports both bounds and nonlinear inequalities and equalities to set bounds on a parameter one neeeds to spefy them by hand- a very good / necassary bound for spherical lenses is enforced below" ] }, { "cell_type": "code", "execution_count": 4, "id": "7e02802a", "metadata": {}, "outputs": [], "source": [ "lens1_surf1 = dit.Aspheric(0.0)\n", "lens1_surf1.curvature.bounds = [-1./lens_aperture_r,1./lens_aperture_r]\n", "lens1_surf2 = dit.Aspheric(0.0)\n", "lens1_surf2.curvature.bounds = [-1./lens_aperture_r,1./lens_aperture_r]\n", "lens2_surf1 = dit.Aspheric(0.0)\n", "lens2_surf1.curvature.bounds = [-1./lens_aperture_r,1./lens_aperture_r]\n", "lens2_surf2 = dit.Aspheric(0.0)\n", "lens2_surf2.curvature.bounds = [-1./lens_aperture_r,1./lens_aperture_r]\n", "detector_surface = dit.Plane()\n", "light_transform = dit.transforms.Distance(-10.)\n", "light_transform.distance.requires_grad = False\n", "#source = dit.source.CollimatedMonochromatic(light_transform,source_aper_r,0.5)\n", "source = dit.source.CollimatedMonochromatic1D(light_transform,source_aper_r,0.5)\n" ] }, { "cell_type": "markdown", "id": "51545f7a", "metadata": {}, "source": [ "It might also be wise to specify bounds on the central thickness of a lens. This can be done by specifying bounds on the transformation that connects the lens surfaces internally." ] }, { "cell_type": "code", "execution_count": 5, "id": "1b01e9c5", "metadata": {}, "outputs": [], "source": [ "lens1_transform = dit.transforms.Distance(5.0)\n", "lens1_transform.distance.bounds = torch.tensor([0.,torch.inf])\n", "lens1 = dit.Lens(lens1_transform,5.0,lens1_surf1,lens1_surf2,BaSF,lens_aperture_r)\n", "lens1._transform2.distance.bounds = torch.tensor([0.,5.])\n", "lens2_transform = dit.transforms.Distance(10.0,parent_transform=lens1)\n", "lens2_transform.distance.bounds = torch.tensor([0.,torch.inf])\n", "lens2 = dit.Lens(lens2_transform,5.0,lens2_surf1,lens2_surf2,BaSF,lens_aperture_r)\n", "lens2._transform2.distance.bounds = torch.tensor([0.,5.])\n", "det_transform = dit.transforms.Distance(50.0,parent_transform=lens2)\n", "det_transform.distance.bounds = torch.tensor([0.,torch.inf])\n", "detector = dit.Detector(det_transform,detector_surface,det_aper_r,is_square=False)\n" ] }, { "cell_type": "code", "execution_count": 6, "id": "cc69dfb1", "metadata": {}, "outputs": [], "source": [ "system = dit.SequentialOpticalSystem(\\\n", " {\"light_source\":source,\"detector\":detector,\"lens1\":lens1,\"lens2\":lens2})\n", "\n" ] }, { "cell_type": "code", "execution_count": 7, "id": "2de703fe", "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "c:\\Users\\marti\\anaconda3\\envs\\working\\Lib\\site-packages\\torch\\functional.py:505: UserWarning: torch.meshgrid: in an upcoming release, it will be required to pass the indexing argument. (Triggered internally at C:\\actions-runner\\_work\\pytorch\\pytorch\\pytorch\\aten\\src\\ATen\\native\\TensorShape.cpp:4383.)\n", " return _VF.meshgrid(tensors, **kwargs) # type: ignore[attr-defined]\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "WARNING: ray_paths will project the ray position onto the y-z plane!\n" ] }, { "data": { "image/png": "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/fffb0Z9brzxRnNU3cSJE83Efvfo087sB4IPOo07rJyXl2f28R77Tcx9nJ+fT090APfQUDf0rFixQuvWrTOHkR7L7Q/3SJdj+8Q93N39QKBP2kdBQYE++eQT8+22ubijD+7wfvN9+qBjubt3jz+NgzvPpF+/fua++3fhfrAe+3fg7pJxjyri76D9NDY2mnmdx3K/DLufA53aD+02TRo4DcuWLTMz9BctWuR8+umnzu233+6kpqY61dXVtF8HuPPOO52UlBTnd7/7nbN3795gaWxsDG7zox/9yOnbt6+zbt06Z9OmTU5+fr4p6DjHHtVFH3S8jRs3OrGxsc5jjz3mfPbZZ87ixYudrl27Or/5zW+C2zzxxBPmvWjlypXOxx9/7Fx77bVO//79na+//roTamiHSZMmOd/61rec1atXO7t27XLefPNNp1evXs6Pf/zjTu0Hgg863bPPPms+aOPj483h7R988AG90EHc7zYnKgsXLgxu476h3HXXXU6PHj3Mh8G//du/mXCEzgs+9EHHW7VqlXP++eebL16DBw92XnrppRbr3UOpZ8+e7WRmZpptCgoKnMrKyk6omT3q6+vN/3v3/T8xMdEZMGCA8+CDDzo+n69T+yHK/af9xo8AAADCF3N8AACANQg+AADAGgQfAABgDYIPAACwBsEHAABYg+ADAACsQfABAADWIPgAAABrEHwAeFpUVJQpqampIXn9RYsWBevgXmkaQHgj+ADwvIULF5qLTobCDTfcoL1793IxS8AjYkNdAQA4W+5oT0ZGRkgaskuXLqbEx8eH5PUBtA0jPgDCxhdffBHcbXRsGTlyZJue56c//akuuugivfLKK+rbt6+Sk5N11113qampSSUlJcrKyjJB6bHHHmvxc+5rvfjii7rmmmvUtWtXnXfeeSorK9POnTtNHZKSkjR8+HD96U9/auffHEBnIfgACBs5OTlmt1Fz2bx5s3r27KkRI0a0+bnccPL222+rtLRUS5cu1csvv6yrr75af/nLX7RhwwbNmzdPDz30kMrLy1v83KOPPqpbbrlFW7Zs0eDBgzVhwgTdcccdmjVrljZt2iT3us533313O/7WADoTu7oAhI2YmBgzGuM6fPiwxo0bZ+bOuCM4bRUIBMyIT7du3TRkyBCNGjVKlZWV+u1vf6vo6GgNGjTIhJ/169frkksuCf7c5MmT9e///u/m/gMPPGBef/bs2SosLDTL7r33XrMNAG8i+AAIS7fddpsaGhq0Zs0aE1Ta6tvf/rYJPc0yMzNNsDr2udxltbW1LX4uNze3xXrXBRdc0GKZG8rq6+vVvXv3NtcLQGgRfACEnZ/97Gd65513tHHjxhbhpS3i4uK+MX/nRMvckaGT/Zy7/mTLjv85AN5A8AEQVt544w098sgjZn7OOeecE+rqAIgwBB8AYWPr1q1mYrE7t2bo0KGqrq42y91DxdPS0kJdPQARgKO6AIQN96ipxsZGs6urd+/ewTJ+/PhQVw1AhIhy3GMzAcCj3Dk3K1asMEeAhZJ7nh/33EG/+MUvQloPAKfGiA8Az7vpppuUnZ0dktdevHixOUHie++9F5LXB9A2jPgA8DT3rMou91D1/v37d/rru4fc19TUBC+d0atXr06vA4DTR/ABAADWYFcXAACwBsEHAABYg+ADAACsQfABAADWIPgAAABrEHwAAIA1CD4AAMAaBB8AACBb/H9yC0wfxDGJRAAAAABJRU5ErkJggg==", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "x,weights = source.sample([11],\"simpson\")\n", "O2,D2,wl,n_func_enviroment,meta_data = system(x,[\"light_source\",\"lens1\",\"lens2\",\"detector\"])\n", "dit.plotting.system2D.plot(system,meta_data)\n" ] }, { "cell_type": "markdown", "id": "b6d060c4", "metadata": {}, "source": [ "It's also possible to look at all currently defined bounds with the following code" ] }, { "cell_type": "code", "execution_count": 8, "id": "cb3efcb6", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "{'modules_dict.light_source.transform.distance': array([-inf, inf]),\n", " 'modules_dict.detector.transform.distance': array([ 0., inf]),\n", " 'modules_dict.detector.transform.parent_transform.distance': array([ 0., 5.]),\n", " 'modules_dict.detector.transform.parent_transform.parent_transform.distance': array([ 0., inf]),\n", " 'modules_dict.detector.transform.parent_transform.parent_transform.parent_transform.distance': array([ 0., 5.]),\n", " 'modules_dict.detector.transform.parent_transform.parent_transform.parent_transform.parent_transform.distance': array([ 0., inf]),\n", " 'modules_dict.lens1.surface1.surface.curvature': array([-0.04545455, 0.04545455]),\n", " 'modules_dict.lens1.surface1.surface.conic_coeff': array([-inf, inf]),\n", " 'modules_dict.lens1.surface2.surface.curvature': array([-0.04545455, 0.04545455]),\n", " 'modules_dict.lens1.surface2.surface.conic_coeff': array([-inf, inf]),\n", " 'modules_dict.lens2.surface1.surface.curvature': array([-0.04545455, 0.04545455]),\n", " 'modules_dict.lens2.surface1.surface.conic_coeff': array([-inf, inf]),\n", " 'modules_dict.lens2.surface2.surface.curvature': array([-0.04545455, 0.04545455]),\n", " 'modules_dict.lens2.surface2.surface.conic_coeff': array([-inf, inf])}" ] }, "execution_count": 8, "metadata": {}, "output_type": "execute_result" } ], "source": [ "\n", "bounds_numpy = dit.optimize.get_bounds([param for param in system.parameters()],\"bounds\")\n", "bounds_numpy\n", "\n", "named_params = [param for param in system.named_parameters()]\n", "names_params = []\n", "num_elems = []\n", "for name,param in named_params:\n", " names_params.append(name)\n", " num_elems.append(torch.prod(torch.tensor(param.shape)))\n", "names_params,num_elems\n", "named_bounds = {}\n", "for k in range(len(names_params)):\n", " named_bounds[names_params[k]] = bounds_numpy[k]\n", "named_bounds" ] }, { "cell_type": "markdown", "id": "71ffb99f", "metadata": {}, "source": [ "With the LEQZero class one can define a constrain that should be less than or equal zero" ] }, { "cell_type": "code", "execution_count": 9, "id": "2ab7e5f5", "metadata": {}, "outputs": [], "source": [ "\n", "def detector_zpos_constraint():\n", " return det_transform.get_transformation_matrix()[2,3]-75.\n", "\n", "constraint_zpos_det = LEQZero(detector_zpos_constraint)\n", "constraints = [constraint_zpos_det]\n" ] }, { "cell_type": "markdown", "id": "e391f6ff", "metadata": {}, "source": [ "Below is the source code for running the minimization routine - **as of now it is always required to define a callback**\n", "\n", "There are a lot of warnings when running the code but they can be ignored - the optimizer will not break even if rays do not find surface intersection due to a bad parameter set" ] }, { "cell_type": "code", "execution_count": 10, "id": "6759ce54", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Ray intersection FAILED to converge after 100 iterations!\n", "This is totally normal durring optimization when a bad parameterset is chosen.maximum svals are: [tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan)]\n", "Ray intersection FAILED to converge after 100 iterations!\n", "This is totally normal durring optimization when a bad parameterset is chosen.maximum svals are: [tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan)]\n", "Ray intersection FAILED to converge after 100 iterations!\n", "This is totally normal durring optimization when a bad parameterset is chosen.maximum svals are: [tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan)]\n", "Ray intersection FAILED to converge after 100 iterations!\n", "This is totally normal durring optimization when a bad parameterset is chosen.maximum svals are: [tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan)]\n", "Ray intersection FAILED to converge after 100 iterations!\n", "This is totally normal durring optimization when a bad parameterset is chosen.maximum svals are: [tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan)]\n", "Ray intersection FAILED to converge after 100 iterations!\n", "This is totally normal durring optimization when a bad parameterset is chosen.maximum svals are: [tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan)]\n", "Ray intersection FAILED to converge after 100 iterations!\n", "This is totally normal durring optimization when a bad parameterset is chosen.maximum svals are: [tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan)]\n", "Ray intersection FAILED to converge after 100 iterations!\n", "This is totally normal durring optimization when a bad parameterset is chosen.maximum svals are: [tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan)]\n", "Ray intersection FAILED to converge after 100 iterations!\n", "This is totally normal durring optimization when a bad parameterset is chosen.maximum svals are: [tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan)]\n", "Ray intersection FAILED to converge after 100 iterations!\n", "This is totally normal durring optimization when a bad parameterset is chosen.maximum svals are: [tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan)]\n", "Ray intersection FAILED to converge after 100 iterations!\n", "This is totally normal durring optimization when a bad parameterset is chosen.maximum svals are: [tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan)]\n", "Ray intersection FAILED to converge after 100 iterations!\n", "This is totally normal durring optimization when a bad parameterset is chosen.maximum svals are: [tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan)]\n", "Ray intersection FAILED to converge after 100 iterations!\n", "This is totally normal durring optimization when a bad parameterset is chosen.maximum svals are: [tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan)]\n", "Ray intersection FAILED to converge after 100 iterations!\n", "This is totally normal durring optimization when a bad parameterset is chosen.maximum svals are: [tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan)]\n", "Ray intersection FAILED to converge after 100 iterations!\n", "This is totally normal durring optimization when a bad parameterset is chosen.maximum svals are: [tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan)]\n", "Ray intersection FAILED to converge after 100 iterations!\n", "This is totally normal durring optimization when a bad parameterset is chosen.maximum svals are: [tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan)]\n", "Ray intersection FAILED to converge after 100 iterations!\n", "This is totally normal durring optimization when a bad parameterset is chosen.maximum svals are: [tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan)]\n", "Ray intersection FAILED to converge after 100 iterations!\n", "This is totally normal durring optimization when a bad parameterset is chosen.maximum svals are: [tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan)]\n", "Ray intersection FAILED to converge after 100 iterations!\n", "This is totally normal durring optimization when a bad parameterset is chosen.maximum svals are: [tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan)]\n", "Ray intersection FAILED to converge after 100 iterations!\n", "This is totally normal durring optimization when a bad parameterset is chosen.maximum svals are: [tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan)]\n", "Ray intersection FAILED to converge after 100 iterations!\n", "This is totally normal durring optimization when a bad parameterset is chosen.maximum svals are: [tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan)]\n", "Ray intersection FAILED to converge after 100 iterations!\n", "This is totally normal durring optimization when a bad parameterset is chosen.maximum svals are: [tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan)]\n", "Ray intersection FAILED to converge after 100 iterations!\n", "This is totally normal durring optimization when a bad parameterset is chosen.maximum svals are: [tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan)]\n", "Ray intersection FAILED to converge after 100 iterations!\n", "This is totally normal durring optimization when a bad parameterset is chosen.maximum svals are: [tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan)]\n", "Ray intersection FAILED to converge after 100 iterations!\n", "This is totally normal durring optimization when a bad parameterset is chosen.maximum svals are: [tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan)]\n", "Ray intersection FAILED to converge after 100 iterations!\n", "This is totally normal durring optimization when a bad parameterset is chosen.maximum svals are: [tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan)]\n", "Ray intersection FAILED to converge after 100 iterations!\n", "This is totally normal durring optimization when a bad parameterset is chosen.maximum svals are: [tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan)]\n", "Ray intersection FAILED to converge after 100 iterations!\n", "This is totally normal durring optimization when a bad parameterset is chosen.maximum svals are: [tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan)]\n", "Ray intersection FAILED to converge after 100 iterations!\n", "This is totally normal durring optimization when a bad parameterset is chosen.maximum svals are: [tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan), tensor(nan)]\n" ] } ], "source": [ "import matplotlib.pyplot as plt\n", "\n", "num_rays = 128\n", "\n", "def merit_func():\n", " x,_ = source.sample([num_rays],\"midpoint\")\n", " O2,_,_,_,_ = system(x,[\"light_source\",\"lens1\",\"lens2\",\"detector\"])\n", " out = torch.mean((O2[:,1])**2.0)\n", " return out\n", "\n", "params = system.parameters()\n", "def callback():\n", " pass\n", "out = dit.minimize(merit_func,system.parameters(),constraints=constraints,tol=1e-6,callback=callback,method=\"SLSQP\",call_before_minimize=True)\n" ] }, { "cell_type": "markdown", "id": "25df75bf", "metadata": {}, "source": [ "With this it possible to obtain the final focussed optical system" ] }, { "cell_type": "code", "execution_count": 11, "id": "c8c5261d", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "WARNING: ray_paths will project the ray position onto the y-z plane!\n" ] }, { "data": { "image/png": "iVBORw0KGgoAAAANSUhEUgAAAj4AAAGdCAYAAAASUnlxAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjgsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvwVt1zgAAAAlwSFlzAAAPYQAAD2EBqD+naQAAinZJREFUeJzt/Qd4Y3eV/48f22oukty7PWNPtadnkkxmMukhQzbsJgSy1BBI/rALgQXCH0KWDssGwnepS9+QsLsJBBZCSIAUkpA2fTIl05s97r3ItqxiW7/nnKt7LdmyLdmSVe779TyfuVfF8pXk0X3rnPc5J83n8/kIAAAAAEAHpMf7AAAAAAAAFgsIHwAAAADoBggfAAAAAOgGCB8AAAAA6AYIHwAAAADoBggfAAAAAOgGCB8AAAAA6AYIHwAAAADoBkO8DyDRmJiYoLa2NrJarZSWlhbvwwEAAABAGHA/5qGhISovL6f09JnjOhA+U2DRU1VVFc5rDAAAAIAEo7m5mSorK2e8HcJnChzpUV84m80W23cHAAAAAFHB4XBI4EI9j88EhM8U1PQWix4IHwAAACC5mMumAnMzAAAAAHQDhA8AAAAAdAOEDwAAAAB0A4QPAAAAAHQDhA8AAAAAdAOEDwAAAAB0A4QPAAAAAHQDhA8AAAAAdAOEDwAAAAB0A4QPAAAAAHQDhA8AAAAAdAOEDwAAAAB0A4QPAAAAAHQDhA8AAAAAdAOEDwAAAAB0A4QPAAAAAHQDhA8AAAAAdAOEDwAAAAB0A4QPAAAAAHQDhA8AAAAAdAOEDwAAAAB0A4QPAAAAAHRD0gifH//4x7R+/Xqy2Wyytm7dSn/5y1+0210uF919991UUFBAOTk59La3vY06OzvjeswAAAAASCySRvhUVlbSN77xDTpw4ADt37+frr32Wrr55pvp2LFjcvsnP/lJevLJJ+m3v/0tvfTSS9TW1ka33nprvA8bAAAAAAlEms/n81GSkp+fT9/61rfo7W9/OxUVFdGjjz4q+8zJkyeprq6Odu3aRZdddlnYj+lwOMhut9Pg4KBElgAAAAC94vP5yDvukX1jhonS0tIoUQn3/J00EZ9AxsfH6de//jWNjIxIyoujQF6vl66//nrtPqtXr6bq6moRPrPhdrvlxQpcAAAAACARPd98+l9kqQIo2Ukq4fPGG2+If8dsNtM///M/0+OPP0719fXU0dFBJpOJcnNzg+5fUlIit83G/fffLwpRXVVVVTF+FgAAAACIF0klfFatWkWHDh2iPXv20Ic//GG644476Pjx4wt6zPvuu0/CYupqbm6O2vECAAAAILEwUBLBUZ3ly5fL/ubNm2nfvn30ve99j97xjneQx+OhgYGBoKgPV3WVlpbO+pgcPeIFAAAAgNQnqSI+U5mYmBCPDosgo9FIzz//vHbbqVOnqKmpSTxAAAAAAABJFfHhlNSNN94ohuWhoSGp4Prb3/5GzzzzjHhz7rrrLrrnnnuk0ovd3B/72MdE9ERS0QUAAACA1CZphE9XVxe9733vo/b2dhE63MyQRc+b3vQmuf073/kOpaenS+NCjgLt2LGDfvSjH8X7sAEAAACQQCSN8HnwwQdnvd1isdAPf/hDWQAAAAAAKefxAQAAAACIBAgfAAAAAOgGCB8AAAAA6AYIHwAAAADoBggfAAAAAOgGCB8AAAAA6AYIHwAAAADoBggfAAAAAOgGCB8AAAAA6AYIHwAAAADoBggfAAAAAOgGCB8AAAAA6AYIHwAAAADoBggfAAAAAOgGCB8AAAAA6AYIHwAAAADoBggfAAAAAOgGCB8AAAAA6AYIHwAAAADoBggfAAAAAOgGCB8AAAAA6AYIHwAAAADoBggfAAAAAOgGCB8AAAAA6AYIHwAAAADoBggfAAAAAOgGCB8AAAAA6AYIHwAAAADoBggfAAAAAOgGCB8AAAAA6AZDvA8AgERgwuejsfGJsO6bkZ5GGen4zhCr1zk9LY0MGXh9AQCxAcIHACL6n6dP0P6TXWG/Ft/9+JUQP/MQPff+6FVyecbnvO9X7rqM8m0W/G0CAKIOvlYBQETn2xwRvQ7uME7eIJh9JzrDEj3y+nrx+gIAYgMiPkD3DA67qc/hohu3r6YV1UWzvh4Nrb305EvHyTsWXloMKLg9Y/THV8/TiupCunF73Ywvy2uHGuhUYyeV5mfhpQMAxAREfIDuaWhXoj1lhbY5XwvVe+IN0w8EFJ7b10Qjo166fFPNrC9Ja9cgrajIpbS0NLx0AICYAOEDdE9D+yBZs82Uk2We87XI8AufMUR8wqZ/yEXPH2ihTXWVZMue2bfj8Y5TZ+8QrazK1f3fJAAgdkD4AN3D/p7SAmtYrwMiPpHz5GsNZDJm0MX1lbPer73bQT4f0XIIHwBADEka4XP//ffTJZdcQlarlYqLi+mWW26hU6dOBd3H5XLR3XffTQUFBZSTk0Nve9vbqLOzM27HDBIfLq1u6Rqi0jDSXIxaxg6PT3jwa7v/RCdduq6aTMbZLYWt3YOUk2mkkjz4ewAAsSNphM9LL70komb37t303HPPkdfrpRtuuIFGRka0+3zyk5+kJ598kn7729/K/dva2ujWW2+N63GDxKa1e5jGxn1UWhhexEdNdUH4hMcTr5ynXGsmrVlWOud927oGaVmFHf4eAEBMSZqqrqeffjro8sMPPyyRnwMHDtCVV15Jg4OD9OCDD9Kjjz5K1157rdznoYceorq6OhFLl112GaUCPp+Pxt1u2c8wm3GSWCCNHQ5KT0+joryciFJd4TY71DOnm/vpZFM//d0VdXP2POLXk/09W9csW7TjAwDok6QRPlNhocPk5+fLlgUQR4Guv/567T6rV6+m6upq2rVr14zCx+12y1JxOCLr57LYjLlc9Oj7viD7y9/xLko3GuN9SEnN0VNdVDQ6Rh1HmshszSSL1UJmq4WMmaaQolIzN0P4zCnQuXy9pMBKyyoL5nwfWPSMT/gk4gMAALEkKYXPxMQEfeITn6DLL7+c1q5dK9d1dHSQyWSi3NzgipCSkhK5bTbv0Fe+8hVKGnxEraT0QWl97FC8jyYlYCmz62hr0HVpGemKCMpRhJDFmilbQ5aZMruGqPt8L7nL7WTOMsXtuBOZo+d76ULHEN1y7dqwopJt3Q4xQFcUhhd5AwAAXQkf9vocPXqUXn311QU/1n333Uf33HNPUMSnqqqKEpY0ouW0R3Y3ffqzlGHCiXe+cHfgB588RhuWlVBhpplcQy5yD42Se9jl33fRcM8QDbT0Bf0cS+u9Z7to789fI1thNhVX51NRVR4VVefJtqDCTgZTUv7Xitpoiqd2NlBliZ2qS/PC+pn27kGqKbNJ2hEAAGJJ0n06f/SjH6WnnnqKXn75ZaqsnCyPLS0tJY/HQwMDA0FRH67q4ttmwmw2y0oW+Nuznbplv2Z9ORksmGc0X0419ZM7L4tWbF1BBfbsGe837h0j97BbRBELoj89d5jWFOWQ2eWl7qZ+Ovt6s6zA9yivzKaJoWK/IMortVG6DoZvHjnbQ209I/T269eHnRbr6Bmiay6avdwdAAB0JXz4w/FjH/sYPf744/S3v/2NamqCO8Bu3ryZjEYjPf/881LGznC5e1NTE23dujVORw0SmebOITIa0inPOnv5dIbRQFl5vBRx5D12gaour6FrLlIig64RN3U3D1B3c78IIWXbR6f2NMqafJwMKqywB0WHeGsrzEkZkzpHe/68q5GqSnOpvDg8v06/Y5RcnjGqLQ+vpQAAAOhC+HB6iyu2nnjiCenlo/p27HY7ZWZmyvauu+6StBUbnm02mwglFj2pUtEFosuFziEqzsuJOL3CBmcugVexZJupanWJrEChPjLo0kSQKoh6mgeoszE4dWbKNCoiaIogyrZnUjJGe9p7w4/2MO09Ds7g0pJSCB8AQOxJGuHz4x//WLZXX3110PVcsv7+979f9r/zne9Qenq6RHy4UmvHjh30ox/9KC7HC5Ij4lNVplQFRgKXZs/Vx4cjODm5mbJq1pVr1/smfDTYMzwlOtRPHed7qPV0V9BjZNksk2JIFURVeQlrqGax9/SeC+LtCTfaw3Caq7QgmzLNSfNxBABIYpLmk4Y/VOfCYrHQD3/4Q1kAzIbT5aVeh4suWhN5FRH38plvOXtaehrlFltlrdhcrV0/PjZB/R2OaYKo6XgHXTjWHvQYbKgOjA6xuToRDNXHG/ukIeRbr1sX0c919DpoVSXK2AEAi0PSCB8AoklL97Bsi/MjFz4Z6WlR7+OTYUinwspcWXVbJ/1rXvcY9bZO9Q/107mDLbJmMlSr2/xFNFQ/s+eCdMCujCDa4/GOUe+Ak2ouTeBKSgBASgHhA3RJS9ewRG7mMjbP7PFZnM7NRrOBSmsLZQXiGvFQT8ukGOpqiq+h+lzrADW0O+gtV9ZH9LidfYoAXVICfw8AYHGA8AG6pLlriApzs+fVN4Y9PoHm5nhgyTZR5aoSWTMZqnu0KNEMhurKXBFBhf502UIM1X/d30z59iyqqYjMM8Udm7lxYUk+BpMCABYHCB+gS1q6R6gwL7zBpIuR6ooGERuqG3qp9YzSEyqkoTpgO5uhuqNvRDo1X79lRcRRJBY+1SWRV9YBAMB8gfABusM7Nk5d/U6qqy2b18+zZyYRhU+khuqJ8QnqY0N1U+SGat4WlOdKKu7FAy2UnWmklUuLIz62rt5hurQu8p8DAID5AuEDdEdHn5MmJnyS6pp3xGeOcvZkgAVcYUWurGmG6raBIDE0k6HaXmKljrEJqqmvIM+gkwwRmMWdox4acrppSen8Im8AADAfIHyA7uCSa6Ygd36+EsXjk/zCZ1ZDdU2hrNkM1bxtPd9DllEv9b58iv708imyltqptK5CVtHyEsqYpcS+y29sriqG8AEALB4QPkB38Bwpe46FTMb5/flLVdfEOOmNqYbq8fEJ+tKDu6ksO4uWmY3UcbyVuk6305kXj8tKN2aI+CmtV4SQtcQe5AFi4cNNCwvsmDcHAFg8IHyA7mjtGaaCeaa51FSXy5O6EZ9wOXy2hwZHPHTTlWupMC+bll2xmibGxqnnfBd1nmijjhOtsuV1mPbJrLMSiQaVU/GqMurqH6aq4tSZUwYASA4gfIAuIz71taXz/nkeizI+Ed9y9kTg5cOtVF5kE9Gjkm7IoOKVZbLW3byZXA4ndfjFT8fJVmrYeVoWG67HbJlUsb6chgdGpRINAAAWAwgfoCuGRz007PRSvn1hER9vCnt8wqG9Z4TOtQ7Smy9fPev9LLYsWrpluSwuq+9v7pVIUPuxFupt6KaOl8/SD145R0vWllH95bW06tKllGk1L9rzAADoDwifJIOb1KmxBj6R8ALh09Y9wi/ivI3NWsQnzg0M482rR1opy2KkZZUFYf8MR3nylxTKsm5cQk88fZBuXl5ILYdaqPGNNllP/3wn1W6sEBG04uJqMmcm5kBWAEDyAuGTbPiIXqe3yO7rdzwa76NJSjjJ9erhFjJlm8mUZSZjlkm2ymX/vizTtPvwCIiMjDQx9uoVj3ec9p7opLXLy8XoPR+6+4cpI8tEV791A6W/bSM5eobpxK4GOv7aeTp7oFmWwZhByzdXUf32ZbRsY6VUmwEAwELBJ0kSYiWl227B2nWUlr44AyhTqYfPiNNLmZkm8jg9NNg+QOOesbB/XsqzjRlkSE+j3/WPUF6plfJKbJRbaqO8EivZCrIXbShovDh4pptcnnFas3xyXEak9PSPUBm/Vv6OzTw7bMvfr5PV1+6g4zvP0fFXz9PJ3Y2yeMTGykuWSCSoZn2FDHUFAID5AOGTZHC6YCXtkf3r7v0EGSwoBY6E7//2EFnTDXTD9jrtOq5EYhHkcbrJM+Ke3He6ycv7U65z9I9Q2rA7aBioCoue3OIcyi1RhFBeqY1yS6yyWCClQtRi5xvtVFliJ3vO/A3JPQMjtLIy9GDS/DIbbX/bJlldTX0SBeJ19OWzsjJzzLRqy1Kq315L1XWlKS80AQDRJfk/hQGIgPY+rugKHlXBlUgWW6ascDhwvIVeP95EX3rvxTTQOUT9nQ7q7xiiAf+WL58/NNnhOJCcvCxNBE1Gi5Qtm3oTvbSbR32cbxukHdtWzfsxxicmqM/hpIqiyXliM8HDU3ld9c7N1H6uRwTQiZ3n6dDzp2Rl52ZK12mOBFWsLE741w8AEH8gfIBucLq8SkVXmAJn1pEVEz6ZZM6LT7hT8bi8miiSbYeD+juHaKDDQW1nuqjlZOe0nzFnGrWUWaAgyk2gFNqe4x1kNmZEZGqeyoBjVEaGlBeGX1nHgqZ8eZGs626/lJpPdYoIOrmrgfb/5bgse1EO1W+rFRFUvDQfIggAEBIIH6AbOvudss2zz7+ii0lnc/Mc1XQmi5GKl+TLmgoPB3X0jCiRIr8Y6lfFUbuDOht6w06hybbYuigptAmfj/Ye76QVS4rIYMiY9+P0DozItiwC4TM13cspLl43fOAyajzaJiLo1J4LtOuJI7Lyy+0igHjxLDIAAFCB8AG6obNPET651oVFfNLT0iViwUIgfR6pFRExft/P5GjQyXYFTodLRFCoNNpsKbSpqTN1nz0x0UgBnWkeoIFhN72pZv6mZqZ30Em2LBNlW4wLPiZ+LWs3VMp68wfH5fVhEXRmfxO9+tuDslh8rtleS3XbakUkAgD0DYQP0JXwsWabybiAaIWa6mK4l0+6IbqeEhYoagpNnYkViGfUSwNdSnRI3apRo5ZTXdR8IkQKLcvk9xVNEUalVrLmh59C23eiU2aclRZaFyx85hvtmQ0uf+fKL16cauSSeBZB5w4204uP7JdVsaKI6i6vFV8QP3cAgP6A8AG6oat/lPIWGO0JEj4TE2SkxfXdcFn3bCm0wZ5hGvAbrFWjNUeO+toGQ6bQuCzcXsQpM45ABRiuOSIVkELzjI3T4bPdtH5lxYKjR/2DTtqwfP4eoXDgVKOa6uKp8qf3XRAR1HCklVrPdNNff7mHltT7u0VvWUpZNlRHAqAXIHyAbuCKpOIC+4Ifhzs3M4k2r4sjN2qKq4YqpqXQRgZd/pRZsLeIhdG5g6FTaNZ8pQptItNEGb0jVLyigsY8Y2TgfkbzYGx8ggaGR6msYGE+q0inyq+/eoWskcFRaUPAIujC8Xa6cKydnnlwp/QGYhHE0SKOkAEAUhcIH6AL2I/TMzhKK5fOfzipitp0L5m6N3OUhgeB8porhaYarUUkdQ5JCo1Ho3DXnQM/f5FeT0+j3Ip8yq8pogJeS4sou9AaViSIK7p8PqLSOKWZOIV40Q11soZ6R+jEbqVbNAs/XtyZe9mmSlqzfRktv6gqJfouAQCCwf9qoAsGhtw0Nu5bsLE5SPgkWMQnVik056iXvviDl2h1vo1yxyaor7Gb+pp6ZeDouZdPyn3MORbKX+oXQjVFMo/LYJ5uXub+PUzJIkZ8ZsJakE2X3rRWFqcET+xURNDpvRdksehRu0XXbqgQUQQASH4gfIAu6B4YlW00hE+GmurSyaDSk0395DYaaMPV9drrx92uB1r7RQTxlPXexm5qP9osS0hLI3t5rkSDCmqKRQzlFNuo3+GknExjVCq6ogmnB7e9dYOs7uZ+vwg6R8deVRany6Rb9OW1tGRNWUL0VAIAzA8IH6Ab4cOZGK7qWiipGPGZjUNnuqk4LztINHK3a3XS+vKrlPEfLsdokBDqu9BDg639dP6103I7D3kdt2dSfmEWdZzvoZKlBdKTJ9Eoqsqjonfk0RX/uEkM4erIjMMvnJaVZbdQ3WVKt2hOGybicwAAzAyED9AFPQOjZMu2zHuaeGjhkzwen/niHRunY419tLmucs778siP8vXVsrRGje39ihDyr2EeCts+QL+49wnKtFqoZn25GIt5y4NKEwn2LJXWFsq65j2XUOuZLv/IjAY68MwJWdxRm/sDsQgqrS1At2gAkgAIH6AL2NjMwicaZOgo4nOqqZ883nGqrSqYX6PGygJZy65YLZVlP33kZdpSYqXsIZeUlqvRFKagwq6IoA0VVF1fSubMxKmu4qgOR3d4XX/HFmo63iGpMJ4cv+fJN2RxF221hJ6jRgCAxATCB+iCnkEX5dmjE1Hgzs16ET6Hz/ZI76MC+8KrsEZGPeRJT5fmgeuWFYoQ4v5CDUfaRARxabk6d4vHgvAMNFUIldUWJoyvho9j6bpyWTvu2qYJuNP7mui13x2SVVSdp4igbbUiiAAAiQOED9AFvYOjtKSiMCqPpaa6JlLc3MwtAI419NKKJdOHsM6HgSHFYF6Ul6mlkgoqcmVdfGM9jY9NyABXVQi1nFQ6Ub/82OtiLl6ytlxEEKfF2IycCHCl1/LN1bK87jE6+7rSLZq3L/3qgKyyZYUigjglxqkxAEB8gfABupjK7vKMRy3VpRePT1PnEA05vVRTEZ0uywNDLjGYF9hCV9ZxF+mqulJZV77jInKNuOnC0XYRQSyGuPEgL0bmnPmjQUvXlpElCqb1hcLl7xzN4uV2emReGIug84dbqP1cDz3/33upqq6E6i9fRqsvWyo9hQAAiw+ET5LBjeSaqV72n//fA1JdA2ZnyOkha0MP9RnO0akznWSwGMloNsrWYDaQMdMkPWeMFoNsM0yGWU2q6mDSVE91HTvfSxaTgcoKoxNdGRwepdwcnpUWXsqKxQyXkPNiuMO0IoJaqfGNNjr43ElZ/F6VLS/UhFDFimIRUfGEuz+vvXK5LOeQa7Jb9LF2iWI9+4tdkiqTkRmXLkkI4QaAXoDwSUK6qFbZPqM0jwNzw+6e5vZB8neZmZ20NE0EiUgSgTS5JUM6WS/00umXz5JveZGMdeDp6Lx4UGaqcLShl6pKc7UIVzRSXUW5849ycJRn05tWy+KKsY7zvZoQ4u7SbWe6xV/Dc7q4187SDUrFWEG5Pa7VVllWC226frWs4X6ndIs+wXPDDrfKevpnr0m3aB6eumJztRw/ACB2QPgkG2lEdfSS7G75+jfJYMY3xbnYc6KDXn69hW65cg2Ne8ZozOUlr9urbF3Kdszt31e3/n3PiJucfSPyc1OF1NHWATo65XdlWs0igKwshPyCSBVG1rxsuY5THPGOSIQTJWvpGqY3XVYetcd0DLtoZaUtagbj8hVFsi5/20YZudF0nNNibXT+cCudOdAki2FfDQsgFkJL15bHNcXEfweX3LhG1mD3EB1Xu0Xva5LF6bLlm6skErRsY+W8Z6IBAGYG/6uSDP7mmkVDsl9cnUcGC6ZKz4WnoZcyS+xUvGL+c7o4wsBCaMw9RiOOUfq/pw/SDRvKqchioKE+p3yTH+5z0hBv+53U3dQ/y5tIlG3LFBEkAskvklSxpF7HE8PjVcl08kKfbKvLolOWzRVcg8MuKrBPnxMWrZEbqsmYcfSOUKPfG8QRocMvnpbFlNYU+IVQBVWtKo6buLAXWWnrzetl9bYO+EXQOekTxMucaZzsFr22POHFMgDJAoQPSHn6h9yUk7WwyBgLEO48zCsjx0xeq4WKVpfS5lWhK554gvnwwKiIoFDCiK9jzwp3Bp6td4wMFg2IGinCKFu7Ljs3U1Ip0e4efOJCPxXlZVN2lHrpuDxj0g+o0L44Qp2jPOuvWSmLfXFdF/pEAHE0qPlkJ3U09NKuJ46QwZRB1XWl/mqxCilDj0dajCvbrrhtE21/+0YRzTwmgyNBR/52RhY3e2RDNIsgPl50iwZg/kD4gJSnz+EmqzV6QzEz/CfGiVmqujiKkFtslTUbHpeXhvtZII0oosgvkjSx1O+knpYBqQqaTZTl5GX6I0aTomhqyo1LwsM5qXN05tSFflpWXUTRTHMxBbbFj1CySCipKZB12c3rpey85WSnJoTUxbCQrFmnls1XyOu2qMealqYNi7363RdT29lurVu0aubmY6rfxiMzlompO57+JQCSEQgfkPL0D7movCR6nXTVb9vRqOpiI2t+GS/brEKEPSxBwigwguS/rqOxj8bPdM/4OGy81nxHU9Jrgdf1O73kcHqoujR6r5ljxC98EqCEm300Imw2VNC1t5NE5i68oXiDWAwdfeWcLIY7MMtYDU6L1ZUuqvGYBQ1XqPG67vZLJVLFIujk7gba+6djslhYa92i4xStAiDZSCrh8/LLL9O3vvUtOnDgALW3t9Pjjz9Ot9xyS9AJ4ktf+hL9/Oc/p4GBAbr88svpxz/+Ma1YsSKuxw3ih3dsgoZHvQtOdYUqZ59YpHJ2PplxeTSvworcGe/Hf/+uYQ8N9Y8Ep9YCUmy8z00CZ2u+mGHKoCJDBrWMeGm4PI+sJXayleWStdhGGcb5fWQMjbjJZMygLEvifeRwOnHNFctk8WvIETapFjvcKqMpVJHBHhseWaFGg9grtFgpJ47qcaUarxvu3Crl/GKK3ttIOx8/LIvTZWu2K40SuZINABCaxPsUmoWRkRHasGED3XnnnXTrrbdOu/2BBx6g73//+/TLX/6Sampq6Atf+ALt2LGDjh8/ThaYgHXJ4IhbttEUPixEWPsslvCJ5Li4qoxXcXX+jPdjzwv3lpnqOVKFUUNjLxkcLmo73CQr4BdQTqGVbGV2spXmKosFUYl9ToMwR3zyrOaEj0jw8cl09qo8uvSmtTTuHaeW011K6TmP1TjeLr14/vbofnmdlwZ0k2az8mLAAozL33mNebbRuYMtIoK4io27XPNiUaZ2i7YXJdbwVwDiTVIJnxtvvFFWKPib2ne/+136/Oc/TzfffLNc99///d9UUlJCf/jDH+id73znIh8tSAQGh1XhE92Blxz1GfcllvAJF45ScEk3L/a9TP1/dN9Pd1JdTQldVFtKjo4BcrQPkKNjUNnvGKC2I82yJh+QKDs/RxNCtlI7WXm/xC7NIdWITzz8PdEYSaFGWthzw4JRukn7hdCJXQ2ymPwyHrKqCCG+P0foYg0LTrXJI6dDWfywCGIx1NGwj174330SpWIRtHprjUS3ANA7SSV8ZqOhoYE6Ojro+uuv166z2+20ZcsW2rVr14zCx+12y1JxOByLcrxgcRgY9sg2JzO6/Y64qV+iRXyiQWe/k0ZGvVRRkksWW6as4pVlQfdxD7uChJAqjNqPtcgKJDM3SwSR0+0h65I8qa4qrMxNmIGjkcIVdOpYChaJ/R3cTbqFGg630YWjbXTgmROyWFyyN6fG30SxfHlRzJ8zl/Sv2b5M1uiwm07vvSDl8Y1vtFPLqU567qHdtGRtmb9b9FKJWAGgR1JG+LDoYTjCEwhfVm8Lxf33309f+cpXYn58IH4RHx6RwP6SaKdEUlH4nGsdlDReWeHMaRtzjoWKlvMK/r/mcbppSBNEk8Ko82Qb8Sm/u6GH/utvZ6SEvGRpAZXWFsoAz9LaAvEuJZsY4r8BNqXnl9XT5h310uuJq7AUf1AbtZ7pEsHxym8OSvSHo0CqPyiv1BrTtF9mjpk2XLtS1sjgqBiiORLE3iBeT/98J9VurBARtOLiajJHqW0BAMlAygif+XLffffRPffcExTxqaqqiusxgeh6fDjaE+2TDEd8UnFW1/nWQSrKyyHTPEzM3OOooLZYViCjIy56+H9focuX5FHmqJfaz/dIeX7r6S7tPqoYUoRQcoohPlZOK/G64jYesupRuklLWqyNTu+7IIth340qgtgnFMvoC6c0WZjxcvQMS2pOJsgfaJbF1X5at+hNVVL1BkAqkzJ/4aWlSlfezs5OKiubDM3z5Y0bN874c2azWRZITRwjHsrKjH4JMnt8JpLU4zMb59scVF4yc+XYfHCP+6Th47prV9LKKqVEfsw7Tt1NfdR+vpc6znXLtv1c9zQxxCZdRQglnxjivkkrL1kii+ERFdJJ+rAyZPXQX0/JYo9UWW2hJoQqVxaLtygW2ApzaMvfr5PV1+6gEzvP+0vkG2VxuoyPl0UQHwu6RYNUJGWED1dxsfh5/vnnNaHD0Zs9e/bQhz/84XgfHogTg8MeyrJEP4zPEaRU0z3Dox7qGRylzWuqo/y4ioeOJ7OrcJShbFmRLHrT6mAxdK6HOjgqdL5XUkc8gFSFoxElS/MD0mSFUrqdDGKIq742XrdKFqfFOht7NSHEPXr4ee/8/WF5jtX1k92k2RMVi7QYp+l4zhmvrqY+pVHia+fp6MtnZXG6TB2ZwceTDK8xACknfIaHh+ns2bNBhuZDhw5Rfn4+VVdX0yc+8Qn6t3/7N+nbo5azl5eXB/X6AfqL+JQVZ8Um4pNiqa4LHcoMuJKC6JZlDzsVg7k9QPiEIkgMBYz+6GrqFyGUSmKIj019rtveukE6eDef6NDSYlyVxYvhLtwsgCQttj42Q1a5/QGvq965WV5nFkE8O+zQ86dkcUdrNnSzCKpYWZzwbQkASBnhs3//frrmmmu0y6o354477qCHH36YPvOZz0ivnw996EPSwHD79u309NNPo4ePjuEp47UxifhEp3NzInGhw0GZZgPZc6Jbdj4y6iGzKYPM80jfcLk2V0TxCiWG1OhQaDHEabKCpBBD3BGa/TW8mKG+EUmHqUJIndnFsMhThVDl6pKoenJY0KiC7Nr3XkrNp/zdonc10P6/HJfF/qS6bTW05vJlVLw0HyIIJB1JJXyuvvpqKSGd7T/tV7/6VVkAjI1PkNM9RlkxGDPA5ubZ/haTNeJTnB/9aqORUTfZs6Pno5tNDKlCSBFDSlVVMooha342rbtqhSz+O+PBpdqQ1eMd1NnYR7v/+IZEyarqSjQhxDO+otVNmh+HB6LyuuEDl0n/IhFBexpp9xNvyMovt2sjM2brKg5AIpFUwgeASOBRFUx2jDw+qWRu5pNrU+cQ1dUqRQLRjvjYs2NbLj2jGLrQL1Vkc4khtaw+EcVQ4OBSNiXz82o+xd2kWxSPkH8R7aMsu4Vq1imdpFkIWQuyo3IM/Hqo8812fHCbRKJ4gvyZ/U306m8PyuLjExG0rZZySxanizUA8wHCJ8mQgZWkpCJ4zIDBPB7vQ0pYOnuHKd0zRoYJn5wsMgwZUfs2rHh8KGUYHPGIUCzOj/54A6fLQ2X5i9+1WcTQiiJZM4khjhCFFEM1BVJplYhiiJ+XTJBfVy6XuU9P49HJtBgLEl4MG6OVaFA5VdeXSdXWgn+/MUN6//Bib9LZ15u1btE8yoNXxYoiquORGVtrJHoFQCIB4ZNs+IjeIKU79RsffzzeR5PwcIu9XfuV3ilMuiFdBm1yubCylP30wMumDBFJctk0/b5y/7Z+cqRNUHNJDllyzFIBw+XLc82sSlRauhRjM/fwiTZOl5esWTNPn08oMXSODdRKj6GWkzOLIfbAcFVUIoghNjuz34YXfzHqbRucHLJ6rIP2/fmYLKXPULEihDYoQ1YXevzsTeIIDy/uW8R9ilgE8e9vPdNNf/3lHhFcMjJjy1LKSsKxJSD1SM5PaZ2TT8qcpLLtV1J6Rmz6faQCXJrNnYiXl+eTb3xCBk7K8owp27Fxco+4tOv5PpH8x2k/3EL/8+djwdcbM0QIWXJMZMk2U2a2f1+EkbIv12X7r/Nfn5ltilnvlnBo7R4hs8lA1ih6cQKFj20R5lZFUwx53ewZ6lNSZOd6ZxdDywr9gqgw7mKI02LsteF1yY1r5O+6lbtJ+2eLNZ/olInzL/36gPwNLuXIkV8I5RYvLD3Fj7f+6hWynA6XeIFYBHETx6Zj7fTsgzvld7EI4l5BizHLDIBQQPgkGZyqqaHDsn/dP32WDJg6PyMvvt5MR15toMvfcXlYr61vIkAcaWssSCxNjPH+OO06eJ4Ks41UV24n17Bbvu26RtyyPzrsIeegi/raBmliPHwfEJ9IFSHkF00BAkoTUgECavKyacEn29buYSrMzYq6sZkN5m7PGFmT7CTH7wXP2uIVqRhS02OJIIZYTKsGZS5V5xlePF1eFUJq40Imr9QWMGS1XP6u5gtHdi5602pZXKGmdotWy/T5uHi6vIzM2FyNbtFgUYHwASkLD9vMNIfvaUhLTyeDmdfcP7O7z0G2smy6yt98LxScdvC6xuRkI6KIxZFfJMl1AddPXvbQcL+TepoHIqoaY+8Gn6gmhZEiiBTxNIOYyjaTOcsoJ+W2nhEqKbJTtBl1KwbznKzoV9YlmhhSKsp6payeIyuB6aCSmvxJMbSskArK7FHzm0UCv/+ccuLF9Hc4lLTYEWXI6uvPnpTFx8ZGcTUaxPvz7eLMHp9Lb1ora6BziI77u0XzEFVe/Lpq3aI3VEjUFIBYAuEDUpYR1xhZYjV3KI3mNDdz9IQFCS/ufRIJvgkfuUe9fmGkRJEChZJryE2jgWLKL5oGu4ep80KfeMHCfR6ccuBOwsN5ObT7SAtl5mbLVHXeZvE2L1umtM8najHqUoSPNQZjQxJaDF3oC6gmm1kMqUJIDNRxEEMc5eF10Q118jfA4k0RQq0SzeL16v8dlL/hwCGrHMWaT3SQq724YSOvnpYBpVHia+c1QzYLdJ4cX7+9Vn5fInioQOoB4QNSOuJjMcXmhMtVXbHs48MnQCVKw+mGyLwXfAIT0aQKpWGPIpLUlNxwsJgaGhwlZ9cwuToHqbl9YIYDIrJYM0UEiRiyK4KIBVKWJpSyxAAeSvjkJFmqa8FiaGWxrJnEEAuM0GKIDdQFcRFDLDLU497+9k3kHvWIOVoVQly6zouxFWZT7QbuJF0hPqEsa+SmZa44u/IdF9EV/7hJxneoIujwi6dlcWl+3WVKt2ge/BqPCBlITSB8QMoy4vKSOUYRH/6ym6h9fPgExikNXuHw+qkueujPx+n/99YtlO4dp9GBEXIOOGlU1ohsnf6to62f+i/0zPhYJk6nBYihYZ+PMrsc1N/YS4aKXLLmZenyBDanGPJXk3FZPY+uUOFIi/QZ8oshjhDlL5IYMmeatLJ1hie7Kz2DlNTYoedPy2JRXFpT6BdC5SJSIklXceSIf57XNe++hFrPdClzw3Y20IFnTsjifkT121gELRMPFUZmgIUA4QNSOtWVZ49N+azSwJBSgs5+p3S3zso0EWWSpLXyqmfxLY16aLTfSaODfoHUHyyOnH0jNNjar/0M9/N97GtPyz77RHhYJ6c8eOXxtti/Sqy6qvSZVQxpg1pnF0NcVs9CYDHEEE9233DtSlmcilWGrCoiiI+Pj3fn4wFDVv2zxYqq8sIWKvwcWDjxuv6OLVKBpkyPb6A9Tx6Vxak5tVs0PzYAkQLhA1IWp2uMyopik+pSprOnhvLp7HNSrjW8wZfiW8oyy7JXzHzSGXN7RQQdeL2BWho66dq6EhroGhJzK2/PH1IGcE4l02rWRFBeiU229mIr5RVbJb2S6p6PmcQQiwz2Cmli6OQMYkgrrY+tGOLH5VQcr623bJBjlCGr/rEagUNWc/J4yKpSNs9pMb4cDvxe8/157bhrqzy2mKL3NdFrvzski4WPKoJYEAEQDhA+IGXhiiIejhkL+HSSIrqHugdGKdca3Qn2XBlnLbETFeaQOX1CSqkD4Y6/bMRmIdTf6ZDtYNcw9Xc5qLtZmbkV6mTLJnFVGE0KJN63SbVaKqZAWAypUZBQYkiNDoUSQ9ykMLCaLL/UFhMxxMdYu7FS1nU8LqbfqQxZ9QuhN146K4vh0RaqEKqqKw2rlJ3L35dvrpbFz/3cQaVb9NkDzdKTiBeLPhZAddtqyRalUR0gNYHwASkJ+2/cnnFpyhcLUmlWFwufitL8mDw29/DJskx/D9jIy9/WQ6UqOJI2MjCqRYj6RRQpW76OxzPQG9N/F6fJNEEUKIo4alSYE9cGkYsphhTPkBIdUhsWqpg5MqSKIb+BOhZiiKM6a69cLkuGrDb3U+ORNhFB3NCQ03mctuL3pGp1iSaEOGo117Hwc199WY0sNmCf2dckIuj84RYRgc//914Z3Mp+oNWXLZXO1gAEAuEDUhIWPSxLTFOqjKJFqqS6uKvyqHuM7DmxOTm4PGNkj7CHD7+2fOLkFXhiDxwxIdGirimiiEVSu4M6G3pDPChJFECLFrEoKlZSaby44V6yR4sWKoZUIRRtMSRDVqvzZV36lrU05h0X35IqhFjIcnToxUf2U6bVookg3rKvaC4DtiqwRofcdGqv0i2aJ8nz83z2F7skVcaRoFWXLpHeVQBA+ICUhE/mjDlmwof7+CS/8OkZdMnWnhMbE7jbyxEfc9RHTBRU5MqaCotRPgGKCOpySPpsoNOhCaOpJ/1A0RAoihRhxFubpNfCScckixjiNONkNRmLou7QYkhSZAVRF0Nc8bV0bbmsq999sYy3mByyqvh4eDEFFXa/CKqg6jWlInRmgv1hG69bJYtTbSd2N9AJnhvGj3u4lZ7+2WuSiuMeQdwtmqOOQJ8k5/9mAMKINDCmGKU3UiXi0zs4KltbdmyEj8czRpmLKBr4feHoDa/A2Vsq42MTUpatGa1FIKn7ir8oFBx9CooWBXiMcnKTq0SfT/iziyHFQN18vENmbIUUQ34TNRvQF/rc+b1SB53y/6m+docmgni8xv6/HJeVnpEmpm9VCHGEaiazO79fPKuM12D3kJTGs5hSexGxIFy+uUoiQcs2VibtcGEwP/Bug5TE5RmPrfDxRxeSnT6Hi4yG9Jh1uOaIz2IKn7ngcnq1W3EouLFjkCjy+4p4v+1sl6Ropj2mMYNyi1XTtU3zFfFle3HOrFGKRBdDnY3+2WTn5xJDbJ4uWLAYYuFaUG6XdfGN9SJU2wKGrKpNH19+7HVp7rlkrTJbjNNi/HtDwe0TLrt5vaze1gE6LiLonIghXvwcVm1ZKiKIH2++ozlA8pA4n0gAxCTiE7uRFckve4j6h9wykT1W/haPd5wsMaqsiwXsASmt4VUYsiP2UJ8zwHStVKPJ5a4h6m0dnDGiEViFFmi85jlWiVqiz2KIjce8ZhRD50KIoSyTVk22UDHEIkQ9Bu7yzMKU/Ttq/6BTexplMfyaqrPFlq4tC+nn4fToFbdtou1v30jdTf1aWu3I387IYo8RG6JZBPFg12SK5IHwCeus8P3vf58i5QMf+ABZrZG12gcgmubm2Ke6KCWET05mbAyf7IHyjk2QJUXSCCxQ2O/Di+dITcUz6tVEkBYtYnHUNSxioe1M94yPOVUYqVGjRDPjziWG1NJ69gtxmiqUGFJN1Hml1ogFN78eHJ3hxfDrrI7UYIP0wedOyuLHLVteqAkhnqUWGMkRw/WSfFlXvWsztZ/toWP+KJD6GJwuq9tWQ2suXyaPlezmdzBJWJ9In/jEJ6iyspIyMsI7iTQ3N9Nb3vIWCB8QN9xeRfgYDUh1zcbAsJtysqPbw0fFM6ZE3ZIp4rMQuG+OejKdCnc6Hh5wahEi1WytiiRO5YSC0zmcPlMEEQskm990zQ0dcxIiLTObGGo/1601XrxwvD2kGAqsJotUDPHrsOlNq2VxRK6joTcoLcZikxsd8jGyOVodssqpNPX38Jb9YLyuu/1Saj7ZqXWL3venY7JYjGrdoqvD70QNEpOwv4rt37+fiosnu4nOBiI9IBGET0Z6GqXHqnMtR3zmmM6eDAwOu6m0aHp1VDTw+sVnqkR8FgKnTDitxYub9k2Fy86Vho4OzWytlumzL4WFw7THTEuTbtbTq9EUocRVTvE6QYcUQ6PeydJ6f+PFkGKIR3HURi6GOHpWvrxI1uVv2yi/j3sGqfPFuNkhL4Znf0nZvKTFyrVeP/wYHM3jdcOdWyWKJN2i9zbKOA5enC5bs11plMgCCiQfYX0ifelLX6KcnNn7KQTyr//6r5SfH5uGaHqHvzmep02yP/Kfr1JagvoDEmIMQ5+T9vzyZUpPT5fXiatCZMuXWRRlBGwD99P5vqHvw0KKbx/vGKRxGpdvtFwRYjBlSJmu7Ms2I+G/FXIDxiGnR5nRFQM8Y4rwMadQ48BYwVVGPK2c11TYRM8l36rhWkulydYxTTwEio+gFFpANRqn1xa7kokjYiz6AoVfkBiSarJeeS7s4wmMeilT6xUhxBEifi5z/f/i36d2e2YcvSPU6PcGNbzRSkdePCOL4cev5ZEaGyqoalWxvDYcTVu2qVLWmGcbnTvUolWGsbmaF0es1G7R/JqC5CDNlwqlKVHE4XCQ3W6nwcFBstkSb/aL1zlK37rj0XgfBggDrvYxmoLFkCaO5Prptxn5snm6iJr8GeU6flzl8YMfiz+swxVcLHr+9ac76aYr6mhZ1XQz70Lp6Bmi3zx7iO5978VUiZNCzBj3jtPg1BJ9VSB1OMg96g35c9b8LL8wUiJEgdVo2bmZcRPuocRQb9tAUDWBJob8aTIWReGIocAvkFy+r/qDmk50yuvI8P8lNjarabGpqS0+vjOvN9HxV8/LPDJOsTGVq4q1btHhziNLBjxjbvrm0/8i+/e++ftkMiSW72w+52/EoJONNKL19KzsXvnDn1KGOXH/COPJn3c30Bvn+unt162niYkJ8o1PyIcdf0j5JiZoYtwn17EBV9kG3B7qvkE/M0GnG7to3OOli1cW0ZhnXLoJ89brGZcPUK9nzL+dvI0b63HXWr7MZboxIU1pEKcKJxFIJkUgaULMqIglj89HtoY+6qR0cue3ktFilGWwmMhoNpIh0xh0HT9eJFUuXi3ig6hkLOH3lQeS8poKf691DXsCTNeTzRz5sloePhX++5hahRa4jWXzv1CRIR5NoVWTzRIZUtJjBXOKIf47ZuHEi8vcOdXIs85UIcQdpXkxnAZT02IshFjUsOGZ1+iwm07vuyCRIE6L8ev53EO7acnaMn+36KWScgSJRcTCp7e3l774xS/Siy++SF1dXXISCKSvry+axwemwP+JjeTRymQNltg0nkt2fHxyzzJRZm5svnk17zpFLpeLrn3nRfP6eRZVLH5EIPkF05hXEUgilEQgqWssSFBp1/tF1LR9//3V69wOr3Y9i7dAeJRja6eDQltrQ4gqsyqEVFFk0vanXtfvdJO5b4R6eYREoZsyc8xyckKzuMX9vOATLy+OjoT6O+QUUFAKTSvTH6aeloGQj8tiQPMVTalGY2EQ7RJ97oXEURheocSQWk2mjr+YUQxxmqx4uhjiVKMImw0Vcnl4YJQuBAxZPfrKOVkMz5dThRCLsw3XrJQ1MjgqhmhVBPF6+uc7qXZjhYigFRdXJ0VPJz0QsfC5/fbb6ezZs3TXXXdRSUlJwvsYgD7xeCfIEEv/0wL/7vnEwGuxRyHwiU4VSgdPdNJvnz9Fb796LaWNT5DX5aUxl5e8ox5l3+2dvM7lCdj3ktfpIWffCI37+yXNBDv9fv/vwSMiOBplyTGLkTUzxyQlynyC4uu0fe1ywO3ZZjJaDPjMiSL8N6gOdQ2F2+mPFoWoRmOh0Xq6a9rPcLqVmwYGVqJNjgCxyvseczHk7z49mxhSJ9azKJoqhnJyM2nNFctkcdSMBaBEg2TIagft/dMxWfxcuemjGg266E11tHlHvXQHP7FLEUGqqZr/7rVu0ZuqknYMSioQ8Sv/yiuv0KuvvkobNmyIzREBEAW84xOUEUPhI52bKTlPdKZMXkaasBhoIstExbXF8xYTIqTcAYJIxJEikpqae+nk6XbacVEleZweco3wck9uh3mmliOitB8fvyaGWDRlTRFI2n7AfUQ4maVDLxrSRQaLFJ6YzmsqnA4e6ucSfUeQr0itRjt/qCXkY3L0SRVbk9VoSpk+V6ktJFo0oxhq4JL63nmJIV4c5eF16U1rJfLacrpLE0Kqufxvj/KQVbNUibEQYq/Plr9fR/0dDq1R4sndjbI4Vbjykmqq376MataVS7oSJLDwWb16NY2OKvN9AEhUxsa4nD223pJkrwtwusek1HwhUVsRUllmWVMZsFrI6Ryla9598ayvIUegNEE0PCmM2D/BEQf2qChCyUOjcj83uUc8NNQ3It6McOHnac4yBkeWeF/E0wzCKUBgJWqH5XjBIpIn3vOqrg/R0NHl9ZfoT6bPeGgsD4/lmWicngr1mPbCnBmq0WzyXkT69ypiqL4s6BiniiE+lrnEEG95BAmLFLXk/ep3XSzevcAhqxzp4cWw70pNi73vxreICV3mhr2qpM54cQpYHZlRXV+Kv7NEFD4/+tGP6LOf/az4fNauXUtGY7DJLREroYD+4I7BsU11JWnIJ4BR1xiZY1jSPDY+QcY53gPxrJkNsrjHTcS/wzseFEFShZIqkHifRdJokLByU1/7oFTnRAJHjMxTIkuZfmGkXq9eVoWVWa4z6fIbPUc11EhJKME7MjAalEYLjBqxkAj1/4vfAzVCFDj6g7csmMJ9necUQ/5U2VQxxCJlajUZi6G6rTWy+Hn1dwxNRoOOttGBZ07IYlHHHaRrNpTTWz56pbTVEE/QzgY69PwpWVxNx4/DIogHssJKEhsi/tTLzc2VkrFrr7026Hp+w/lNGh9XKjkAiCdjE74Yp7rSkl330Kh7jMyxmmXGZdYTMRaffr8Q+zF4zSdN5wqMKPmFknJdwGUtPafss3+jq6kvIuHLwk6NIrFIChJIgT6nIL+TcjkZekJFCj8fNkHzChyMqsJGfIkWTRsBomzZxzP9QYls+dnTmjmyMGGhlG23zPo6hhRDTo90g1Zmk/XOKIZU87Qqhi66YTVt3lEnf2MyZFWEUBu1nlEG3b7ym4OSRuSo0dZb1lFmTiY1n+wQIaROo+e+QDwyg0UQpxpT7W8gnkT8qfee97xHojyPPvoozM0gYRkfnyBTBj4oZmPUMxa7Ia7+9yCW4nOhcOoqy2qRFSnsb+EIgSKUpgikgHTd1Mtc+cM9aaZW180GG2jnFEghjOB8f466JOMJkyv/uEMyr6nwl2xOLwUOiA0s0+fyfDYghxKfQb6iwDL9YmtIs7EqTgJns00TQ+d6/N2hZxZD665aQdvfvoncTn83aUmLtUkpPC+Ghc6Ki6opJz9Lnse5g820+4k3ZOWX27WRGYUhXhMQGRF/6h09epQOHjxIq1ativRHAVg0xsZ9lBnLiA9PZ/cl/yBXYwxTMOMTPjKkqPjktIXqASKKbBgzn7i9rjFNGE16mSYvq0LJrfmdlC2XmKuN9sKBu5Wbs2aplJtiDOe0nJbOyzIlpBmchRy38uDF87WmwmZ5R6/iLdIaOmrNHRV/USg4+jStZ5G/Go1vU1+LucSQUlrfO6sY4j4/W/5hnVzP0SMWQrw9/OJp/5Mk6QrNv59FNVfPvfrbg7J4FpyIoG21cjtYBOFz8cUXyxBSCB+QyIyP+2I2p0vFl+TJLhcLH1Ps+opwj69EjvjE88TNVXW8bPNomM2Gbj7RBgqkyajSpBFcS9/5r+eS7EjM4HzyFeO3Pz2nCiStBYG/JQFHliR1NyUqFS8zOEfI8rhKrCS031QRkCG6XHcOSVqKU1HTHtPIDR1zplWj8e/gVNq8xZDV7B/UWiRVYPx7WJg1HuFmiJ3yMwynO0uW5kvDVZ7dxhVkvCpWFFEdj8zYWjMvj5xeiVj4fOxjH6OPf/zj9OlPf5rWrVs3zdy8fv36aB4fAPNi3Oej9BiG+OWRk1v3yCytrKzYRXz4Q5oHxYLooprB5zMWgaNFmocplL8p0M+k+pxGPLOOvpgJTrOFTsMF9GwKakkwGYVi71as4N9TWsMrdEPHoT5niGaOyuptHQz5mBx9ChktKrHKoFZVBPJryeM45hRDtYV08Y31IoTYBM5T5gN9Tfw68d8AC7XWM93011/uEW8SR4JWb1kqxwOiKHze8Y53yPbOO+8MnlQNczNIIPikG/uIT3IT68o3CJ/Eg0+k3HVZnUYeCSwK2KMSKJRGA9Jxk9V0imhS03dDvSPU3dQfUfsHjnBM9SvNeFlrSWDWBMF8fU0sUNhrwysweqPClYBTDddq3yKe/cVCZPpjBpTo+5s5sjjix7f7ewUFi6EexQPkH5mhiqGq+lKpamMBytE7FmgqPJKm6Vi7rGf+a6c0U+QJ8isuXiKvCVig8GloUPoTAJDI8Ek3pqbOJDSMTmVsLLapKJ7+HmvxCRYPFgXq+Iv5mcEV0TS9vcAMxvBhDzmHXNTX7tAGgYZ7nHNVygVe1loSZHHqbnYzOKcn2WPDK9RzHB5wTjFdT1ajKVGdyciOCh9DYJSoek0ZZdss5HGPiWhkQcViqHmKYZuPlQUsG+UdfSOTx+HzSfNIXsqE+SqqZxG0uRrdoucrfJYsWRLpjwCw6PBJN+baJMlDPtxnJ5ZNHkX4pIBABNEygytprkgRM7h7bFr6bZqfaVr6zkOO7mHp9RT2caZNHqcqjLgXU6BACtmSgK/LMorPhlfggFUVfg5KQ0eHmNSVrSKMetsGxQ8U6ni4mzULIzZypxsyZEzMiMMlYopF4dRIGQs/tUcVG73VyjFVBG24dqU0VIxlOjHRmVcta1tbm4ytCDWk9F/+RRlfD0A8wUk3zF5HMYzIcGYDER8QFTO4xSiLu0RHCvcEChZK/uo5NU0X1C18spqO/TzcfToSOBUVzgiVvFKbNEFUBRabo2UuWoDRerIazSFjMUJ90eK0Hjc9ZBHDUW5+Lk6HK+SxTRVB1fWltPnN9bT8oirddYuOWPg8/PDD9E//9E9kMpmooCC4qRLvJ4Lw+eEPf0jf+ta3qKOjQ2aK/eAHP6BLL7003ocFFhE+6SLYEF8flPj+YvboAITfEyjHNE8z+NiEFj3SWgsERZk85HZOCiY1KsURHbczRJPFuZpcThmhwt4gruZi0ceMece06Neow0XD/aNSus/eq9DPPUNScFPn4Y2PTWimao7GFVfn0aYbVtOGq1fqost4xMLnC1/4goyruO+++6TldqLx2GOP0T333EM/+clPaMuWLfTd736XduzYQadOnaLi4uJ4Hx5YLMRIGeOqrpRIB8bwmYj4TIVXCugVjowsyAzu9zUFV8xN8TNNSd+xT6indUAES7ikG9JFHEmqi7/M+JQGoiySvN7Zo1a+CZ9UjD39s52y2MfExustf782OGU3kaZf4eN0Oumd73xnQooe5tvf/jZ98IMfpA984ANymQXQn/70J/rFL34hM8YAAAqxbsAo0jN1PisBiNwMzk0hc8xE06dyzBktZZ/OjMbvaUZwjkQpUSn2/0yN8ESCZ9RLZ/Y3yRLSiNJpM5Evjfo2DVJpVfIHENJ8EY6Y/sxnPkP5+fkJKSI8Hg9lZWXR//3f/9Ett9yiXX/HHXfQwMAAPfHEE9N+xu12y1LhOWRVVVU0ODiYkANXx1wu+tHt3ycPWSizqATfqGegb8hFRkOGTB+PBaNur6SKcvlDLUnpdbhkSKk5RqFtp/gjfGSX7sYAgMVAPaVzJIf31S1/XvHyjU/4r1fuy5GpcFXA5r9bRTs+sJ0SFT5/2+32Oc/fEZ8V7r//fnrLW95CTz/9dMgGhhxxiRc9PT0yJLWkJFhe8+WTJ0/O+Hy+8pWvLNIRAgAAAPOBBYwiaDhNHSxspgudye2kGFpol/qyFfNoNZ6AzEv4PPPMM9rIiqnm5mSDvUrsCZoa8UlkVtEu2V737V+RwYIOnaH4/M920pKaUrpsfWzaL/xt31nq7R+ij9x+MSUr////fIUuWVtNF9VVxuTxn9l5irweN33kHZti8vgAJBscXeGS+1BNH90hmkBq1/v9P5EIGE61sVFZGgyLwXk87OG46RlpVFSVR2uvWk51Vyyh771wL1FPDq2+7HbSpfD5j//4D/HLvP/976dEo7CwkDIyMqizM3jWCl8uLZ3eV4Exm82yQIohIjx2JpYkb+EjsAkylj4fZZBrKrxSAISo9JrquZlS7RXU1VrtZh3p2A8uj882kbUgm4qq82Sfq9TYd8Miasw9Lp4c/l1cxs7jLVT4drXxowxY9c3+fzWv1EYbr19Fm3fUkdE8mcnxjLmJjBNEZcE9g3QlfFgkXH755ZSIcIn95s2b6fnnn9c8PtxniC9/9KMfjffhgUUkFaanxxpuLjjBcfAYId80Y/boAMwfpSR8aiPEqQIm9Byz+Q56ZWExU/foybllZjKYM0TMcNdqR/dIUKNDnu0VqreQNF7MMUmzQ47q8HMJbNwYqkIsPSNN5nttfnOddHXWUy+fiIUPDyjlvjjf//73KRHhtBWbmXmKPPfu4XL2kZERrcoL6IM0im00IxXg5oVsdowVEnPDmwBigFQ9ubz+iIo6qX5qtVMIQeO/noe1RtZ1WplKz12ZgyfVTwoYZVK9mTIDhIw506REW+YYbdF6uksbbTHcPzmDKxB+/PwyG2XZM6XMnoWNc3DU3zPIQ6NDblkMl7Ur/wGDHyPDmE61G6to0/WrZJ4XP44eiVj47N27l1544QV66qmnaM2aNdPMzb///e8pnvAQ1e7ubuk1xA0MN27cKEbsqYZnkNpwt4WYn3STz9IWBM/pGo+l8OGIUuwCSiDJUeZ3TY6YGJ0y3DRQ0KgCR+2uzE0Dw/WrMOx1UTso8/iHoAnxU0ZUqIJGETIm6Y8TqX91cphpR3AnZv9Q01BjNNRhpjXry2WYKQ9K5d/tcXtppN8pg0k54hM02iKNpMeQOStbGhp6Pcrjjvm38twN6RLRWXPFMlq2qVJJlemciF+B3NxcuvXWWymR4bQWUlv6RknjxFD4pEAkw5CRJk3OYukhimVECSSIWTcwPeSc0qxv6mytwOiL0xORWU46G2ebKCc3kwor7WFPa+fr+Wej/bx5OromajRx45AxE87B0GMjMq0WGXCqTmhXt/biHK2RIA8k5XVyV4MIPw324ZTYqLAqTywcPPdruM+p+XoCOy5zlIlHUdRfrgwnZa8QmCTiv4aHHnoo0h8BIC5pnFhHfJI84EMmQ4YMKo2l+BxPAYGY6nD0YXLAp3tmIROi+7A6DDPSWVYczSgOa/jnpJBZ7FEK/PwGuhzTojVKJGc45MR4jq7Yi61UVlsYJGzULUeR+HOJRYsicHrpxM7zsp0qcvLL7DJMNJMntY96qaelX+7X3+HQ0llZNos2m2tibEKiRfXbl9HKS5YojRNBSBDzAikJRxtimcbxpYDyMRnTaWwsfK/DvN6DGAoroMAnUk5tKN17AyqI2PcRNBYhdAVSYFokbLNujllOzMEpouDBnKqAMWepxl1TQhlouTqL51ypwmZyKKgicIKESAA8FLR8uSpsbIqo8Qsba15WkKcnUOSc2NlA7f5ojurFCRQ5tRsrqbS2QDw8HMVpOdlBZ19v1sQlp8LYIM2fPv0dQ/K+8aqqK5HIzurLauY1WkOPhCV8LrroIqmMysvLC+tBt2/fLjOzKioqFnp8AMyLjPT0RYj4JLfy4Y7N3gW0to+3+EwlJkcUqJGWqVPDgwdlqiMKVP9LJCMK+ASqRFPMUgUU5HOZZaK4RGQyjdPMuon8mvLrpgkb/6Rz1UTs6B0JWe3EaTFOPVWuKpkUNWrkptg6Y9qMf5+jZ5jazymRnJAih/wiZ4MickprC8lWlEPtZ7up8Ugr7fvzMXL0jATc10Z5q0vI5fRSx/lu6msblOt5sjuLnbqtNWQrzIn6a5fqhCV8Dh06RIcPH5ZRFeHeP3AMBABx8a/EMuKTAtPfzaYMco6Mx1R86iniI0Mpnd4wfS4Btzn9zeki+Hs1sFlX5kBZKJ/LpIPKo0MbdtWUkdFiSMpmszOl6ZT007CWluoPEDohU3FpRLb8bBE2eVOFTYmNsu2WOV8fTeSw2fhcz6wih6unWKiwyCmtKZCUXcupTmo80kYv/M9e+VnV65RpNYuYyc7LksdvfKON+tqV1BY3FBSxs61WBBFYhFTXddddF/Y36FT5TwWSl4yMtJA5eDAJzzHzDrhj+h6MJVnER2tON7Uh3UyXAzvsjs7DrJtjppy8LCqszJNyadXnokZaJF0UUC6tlk/rpTKHzzmc9plqIhZx0zVEQ30jIV9zNvMqosZGucU5fmGjpKXYX8TCMZJjmK/IUT093c39InR2P3GEmo53aL2A2BO0dG05LV1bRharWaJFp/dc0NJs/BwuvrFeBE9xdXiBBzA3Yf3vaWhooEiprIxNG3wAwsGQnk5e1FLPSiY3Sougn8l8Ij5jMUylzcSYh5vTTfpb1Jb/4n8JMOpySTSXRgcKmIia0/l7q0iJdIl1WiVRkEE3xGW99lCZCr/mk4LGQYMcvRG/jRLBCeVB4nQbl36zaJhmIi6xikCczxfwqSKHBQ7vjw65ZhU5JUsL5H1V4V48PN284UgrNRxpC+rNwx2YazdU0NJ15ZRhyKDT+y7Qvr8c16qzuEvzlmtWiNjhx0YgIU7CZ8mS2Mw7AiBWGAzp5HLF0tzsS3KHDwsfA7k8kZ3oI8GQkT6vqjE++XhdgZ11525Mp/R2Ue4TqkfKTKgdb1m0FFbmzuJzmd5h15xlTCizbqLCKbyhfm7Y55hWHcX7gWMWAmHxwumdQEGj7tsKchYsHBWRM6KIm1lFjk2qpWYSOap4O3+oRRM6XRf6gszQa69cLmJnyboycg646Phr5+npn+8U4zPD1VkX7agTsVO1qiRpfFTJij7ipUB3GKU5X2SlthHBmirJP5uyzEZyx0j4SJqRBYjTQ23nesgjPpY5fC4B0ZdI0pQsPtRoip3NugFddKW6KMD3MrVcmlMi+Ea9cFh0BqajAn02LHJCma/5feM0VIna10atkOLUlDQZjF45dpDI4VTVudlFDgscFjqhRI48HvfcudBLDYcVodN8slPrBs1l5lyhxY/D5egs3nrbBkXsvPq7Q5pBmf9GN1yzUsTOkrVlENGLCIQPSNmITyyNtb4U8LJlZxokIsMl7QZDhpwc+MN7zOUh76iXvC4vjbn9W5eXvKOeyX1ZnsnbRwOuc3m1k0AxET38etOcx8InCz7RZdktSpn01D4uIeYbKQLGLD+b7O9FosNClKuggn02/h43XPo9xe+iwu8ne12mln2zd4W9TbGImE0TOVxhda5nVpEjFVY1hSFFjgo/f4noHG4V07HaP4e/APHPqkKHTdPsIeLXhXv0PPmDl6QxoerrYqGzZvsyuW8kXiMQPSB8QEpi4lk2sTQ3+xYn1cUnHK9nTOvZwf4VTuXwPl/PAoPb1I/7L6u3yf1muT9fHhp2UWGvk/5y4nc07h4TwRJJZZFGGpHBbCSjxUimbDNlF+SQ0WIit89HbX3DtO2iSrLlZob2vfiFDE4A8YXFAkfc1NlRgWXffJl9L6FGRPD7xg37KlYUT0tH5RZZY94xmI97qHdEhI0qcljwaKLED/e/WbqujMqWFflFTsGcESU2q7MRWYnqtFJvqxKpYbgNwIZrV4p4YZ8Rp6oYNlu//uwJOvHaeWo90y3XcRXXykuXiODhbso8hgLEFwgfkJIYpSvx+Lw/TFkA+MYnZOSCsp0g37jPv52gscFR8rlc1Hame1KYeNVtoPCYQaAE3k8TK8pluZ/cf2x+QiQM2EPAH8jpLA7NRsrOzyGDRREvLFoMZgMZM00B1xnJYDH5t8HXcYVRKE9CU3s/nXjxKG25bRMVoLFa3OG/qcGe4ZDVUbzP6apQWPOzqGJl8RQTsU2iNtwwb7H8KJrICYjizCRyOHXE3ZNL2ZcThshRv2TwY6tChweHqmKPBdyKi6vF0Mxih6NFapSRp6gffO6kpLIuHG+XcDC/JpzuYrHDXZRniySBJBA+PPn8rrvuoiuvvDI2RwRmhU+Ep2ir7Hf+23OUxtM4wTR6HaNkGPHQ8yc6J4XLhE8+3LRt4P7EpMiJRGw8/NeTC3v104iMJoOka/jbM4sI9qGo+3y90ZQhImXq/WQ/4Dq+PWPO+/NlgxhD+4dc9MX/2k3/cPUaWlqeHxPxyXi8aCuwWMKARcBkF2IHDXYO+7sRO2io1xmyJQlHIKaOVtCiN1z6HYfS+akiRzUgzypy/CmrSLxBnK5jjw6LnQtH28RfxrCoKV9RpAmd8uVFQWZqFolcjcVih0WSCKQ0ouq6UhkZsXrLUi0KBBKPiP+iBwcH6frrr5dKrw984AMihNCheXEZJqWD9og/lAqmw5/v6eSjwREPpWWkU3p6OqVlpImngL+N8TbdH6mQ6+Q+acH3DfqZdO1neb+le5B8NEGXrCmTE4OIDREdBr/QCCE4tNuULf9MuiE9bv4Ua5byLdTJ/WdigCp83DEsmdcbXD3ElUDqMEx1vIKalgpVjs9/X5yaqa4vnZ6OKrbKCTqeHikROX1Oaj/XPSlyOJIzZdAnR5iWrOF01fxEDsPm+caj7VpUh18z7fFLbRKhYbHDYmrqY/NryyMkjr16js4dbNF8bCyQpLHgZTVSig5SUPj84Q9/oO7ubvqf//kf+uUvf0lf+tKXRAhxFOjmm28moxH5y1jCJ97N9GfZv+6XvyKDBd8qQvHi68305GsN9OF/vDwm70PPaydpYtxD19y2iZIVLjfPMhtoxBUj4WNUviFD+IQPRxuHB5zTq6P8lwP7wQTCFUIF5faAEQv+xn3FNql0W+wBn3OJnOAS8hlETn2ZpKrK5ilyGK4maz3TpRiSj7RS29keLerF6afVly1VojrrK+R1m/bz3nE6f7hVIjsc4VGFJU9YZ7FTv6025M+BxGZeMcyioiK65557ZL3++usysf3222+nnJwceu9730sf+chHaMWKFdE/WgAinEPFH3Kx+DYbq8ddbGw5ZhqZwdsRrYhPLHsFJSM8RmHSRKyKG4c29VuNJEydr8UN+7hyaLLsW6mOYnNxIk7ino/IUTsez/f58O/k0nGO5jQebqMLx9rJ41KHfKbLQE9V6LCYClVVxqlv/jkWO6f2NGrpL/b11F++jOq21UiJOkheFpS8bW9vp+eee05WRkYG/d3f/R298cYbVF9fTw888AB98pOfjN6RAhDhHCqGxY8pRt92U0D3UF6OiYZjlOoyGZWPF3ck079TAD5xcnWPzI+aUvbN26k+FRVOOWk9bQJ8NiwMrPnZCd3nhQXHMKerAkQOp61GBoObE+ZGUeSo8O9oPNomQocFD5edq3BTSkXolFN1fdmMVWYcaeP5WSx2Tuxu0MQZpwg3Xr9Kojvc0ycVvuyAeQgfr9dLf/zjHyXK8+yzz9L69evpE5/4BL373e8mm00ZnPb444/TnXfeCeED4hrxkb/XsfGYCB+OlmekwIdgrtVC59omfQ7RJIP9U+lp5EpB4cNekZmqo9iDE6oBI6ebOP3EHpVgYWOTaeDmzOSo/IlE5KyurwmaXRWNyBRXPjaf6qJGv0+no6E3SDxKj5z15bR0fQXZZvHc8PPg4xaxs/O8Jpi4Uk2dj8Vl+uiinHpELHzKysqkQuZd73oX7d27lzZu3DjtPtdccw3l5uZG6xgBiBizvxLF4x2j7BicUGRkRfLrHsq3mumwsycmj83fjlmAJmOqi70h3LtGqY4aokH/VvHbOLT0x1S4KR9XAE2L2hQrDfuS7SQaKHKUEvLu2UUO98gRkVMok8ajdQzdTf1a88CmEx3a/C4WkzzzisdBcGSHvTdzvcY8MJTFDq/+Dofm99l4nRLZYRN4IkfXQByEz3e+8x267bbbyDKLqZZFz3wGmwIQLSz+VFeshnByxCcVwt55Ngs5uePy2LjmyYm2AB2NcPDnYsAnU+42HDgMMzCCw51/Q5V+c+ddFjRVdaXTS8CLrXJ7MsMpOiWKM1ldNXWWFj/P1VtjI3JU2MStCp2GN9qCjoHFjSp0KleXhPWas8A5vlMROyyi1DL+tVcs0yq5EsUADmJPxP9L2cQMQKJj0SI+sRI+qRHxKVA7zo64Kd+eFROfT7yED6dEpPQ7RHUULzYZTyONyJafLSbYoNJvf9O+bHt8S7+jLXICGwHOKHIuWxqQroq+yGHYgNx8Qu2S3CZRGRWOlK27aoV/yGc55eRmhvWYnLo64Rc7/BwZbiOxastSWrO9lpZtqkp6oQrmB951kJJkmtWIz1js+gSlwAmwwK4IH8ewKybCx2w0kDNGwofFJ5+og6ujWNQoERyeCC5D1aYeU6ZRDMNKyfekgZiro+zcsC8Fv/lrIkcb0DmzyJEBnTyFvLaAsqyxaZfBZmL25qhRHTYWq4NMWYws21QpjQM5EsMG5XDFJqfgTu5upOOvnaPmE51aRRyPiuDIDndf5tJ/oG8gfEBKkumP+MRq+rgS8Ul+H4Cd52RlpNHAcPBJMJqpLqdrbEGRAGXC9/C06ijeql6PQNjjwaXfPENpanUU97XheWGpErWZU+T4DchTRQ4LvMUSOSqD3UNal2SuwtIGm6aRHIPaJblyZXFEaSc2mp/aq3RR5uGhLKr4/WXvD4udVZcujUmUCiQvED4gJcnISCejIT1mzfM4kJBkPtWQcNSqwJZJg1MmV0cLi9lAAzOUbzN8kuITdX9gB2LNRDw0zUSrwicy7qUSNF6B50cVW6UEWS/mVPbCTA7oVLw5U5scssjh9A6nqxZL5KhjHbgfjpq+6msfDD6mS5eK0OEuyZEeDwviMweaZBiodFH2R4sqVxVTnb+LMqfIAAgFhA9IWbgrcawiPjKdPUWiBkV5mdQ/FMOIz7CbOht6leqoKX4bjgKoJ61AWLiwqCmpKVA6EPub9rGw4ZSUHoc+isgJiOLMJXJkCnlt4aKIHIZL+NvOdvvTV23SMVmde8fpRR7WWbOhnGrWV1JeqTXi/z/s2Tp3qEUiO2cPNGtdlPlvZA2LnW01ZC9CF2UwNxA+IGXJtBhjJnwmUsTczJTkZVFzV/e80n1ep4ecAyM0OuD0rxFy8rZ/hEYHnTTcO0xmzxg9GGKYK/dL4RPz1OooTknxt3W9RG3mEjkd55S0VSKJHPX97+8Y0nw6HN1RJ7xzupF74ChCRxnyOZ/3k0UxDw9Vuyi7/Yb0ggq7dFGu31ZDBRVonQIiA8IHpHTEx+UJUbkTLXNzKuS6WPjkZ9HgsIvGxidkfhfD39Tdw6MiZjQhI/uKoBntV0ROqPEKKqZsM5nsmTQwNk6Xb1kiQyADBQ6XE4N5ipyawrhM/2ZfDvtzVLHDVXMq+WV2KQ/n9BV3SZ5vVI7/9rhXD4sdNiqP+tOw/Dez+c1KY8Gi6ryUibiCxQfCB6Qs2RYDOUZjaW5Ong9eTkOMDrul8R6bQV3DHnINu2l0xE097Q6yNvTQqz9/gSacHhE0o4Oj5AvRfVhII7LYsshWnkdZuVmUmZtNmbLNoix1355FGSYDnW/ppadePk6XvWOzGKn1DgsatXR8LpHDAkeETpxEDsPCtuV0lyZ0+HjVSjnuwly3tcZffVW+oDQT/39qP9sj1VjHdzZorwlH/i65aY2IHY4aJdP/OZC4QPiAlCU700jdg5Nze6IJf1Avdjk7ixeXkwWLX7z4BYwiaNwB1/uvU68f8YTuWRNADne0bR+ktIx0ES75SwonRU0eC5ls5XJeNllsmWGnLTjdyIy4vLoTPpMip1crIZ9V5MgU8viJHPXvuqdlYLJL8vEOzUvD7znP2VKFDs+uWkg6Uu3IrHZRZlO7alzf9KbVInaqVpfoOuUJYgOED0hZsi3GmKa65qN7JIU06gkWLCP+6MusAsaj+SfCgqMyWSay5JglBcFpB97nb+nqvmyzlesefOYk1Swvo+1bVkR1rEKmWRE+Q87YvA8JKXL8aSueTB4IV5utvHSJVl0Vb5ETNOSTy8xZ7BxpDTpurpxjkcNih7tVRyM9ydPTubHgsVfPU2/rgGZ+5iaFLHa4DD3DALEDYgeED0jpiE+0uwbzt9SJsXHyub007q9WmipgQkVc1MtupzfkKISZ4BMCixT2xUwKFVW4mDUBk6nu8228n2WKSMCUnummAY836rOksvwnylhNgI8HwwOjAZVVc4gc7pOzrFAqj9jMnQhwBKflZKcmdDob+7Tb+BhVnw4LEJ4KHw3YC6R2UVaHihpMGVKJxWJn2cZKMvh7bwEQa/CXlmTwSXOAimX/7OstlGHSX1lvuLia+og6Bqlx3znyjU2IYBn3jNO4d0y8C5NLvTzmv32cxuW+gfcbown/9exx4O+jLUT04K/2z3kc/C2ZxYmtMGeKUAkUMP7rAgVMlmnRwvwVhTm072RX1B+X53+xYXpoxJvUIidQ6MwmcmSsQ23iiBw1yth1oU8TOtzReMxvSucu1Sxy1NlX0TQNcxRM6aJ8XjozM/z3zN2TpYvy5moyZcLgDhYfCJ9kw0d0ji6V3XPfeSneR5Pw5BPRvpMdEf0MRz24c2yG0SBbg9lA5hyzctmUQRmGDGrrHSJ7bibVLS/0CxXzpJgRATMpapIhbF9RlEPPH2iW1KDFFL2TEZ9EOerjiCRNlwAiR01bDfUGe8RsBdnSj0abXZVgIkeFj1sROm3U8EYrOQcnm0hy9ElJX1VS1ariqEZauOrr1F5F7Fw42q4VAfDvq9++TF47Tq0CEE8gfJKNNKJKOia7K9/7Pko34C2ciT6Hi1482EKXrl9Kdq4yEjEzKWjS1csmQ/D1YURZHvnTASqvzaPrr15BqUBlEdubiXr6R6iyJLp9UbIsJhpKMOHDvpbAKM5sIqd0GRuPixJW5DBsXm863q4InSOtYlBWsRZk0/prVijpq7XlUX8O7Fk7s79JxM75Q61iwmd40CtHdlZfVpOwrxvQJzhrJhn87amEGmT/4h2ryWCJvzkyUekZGKU/dQxT3rpKqirN03U5+1wU52fKiI+uvuGoCx+u7HKMeOIvcrQBnXOJHCWak8gnaxYXMuRTxkHwkM8uTXBwanX55iptyGdBuT3qf6vsEzp3sFnroqymzjgSxmKHy9w5tQtAIgLhA1IWa5aSsnG6ou8vSZXp7CoZ6emS7mLhE22yM03UPxD9x51b5Ch9cqaKHI6ArLykmkoDqqsSWeSocLm3KnR4GCeb5hkWNWXLJ4d8ViwvimjIZ7iw163hDaWL8ul9F7QWCVz5JWJnWy3ll9mi/nsBiDYQPiBlMRkzJIoRC+HDIytSpXOzypISKx05N1nhE03h09jqn8QdQ5HD+46ZRI6/uipZRA7DwubCMWWaOaew+jsc2m1c5cdCQ4Z8rimLmW+Go0jcy0cdGcHViQyPFbn4RqWLcnE1O+kASB4gfEDKwt+ErVkmcrqin2ZJSeFTaqOXDrWSy+0li7//TjTIzjTTyKiXxscnKGOeVWqKyOkN8uXMJnLUlZObHCJHnUslQz79UR3eV4d8slmeGx2KKXl9hYz/iBWcxm093SVi58SuBhoZGNVe3y3XKL12+LVNpVQv0BdJI3y+/vWv05/+9Cc6dOgQmUwmGhiYNO+pNDU10Yc//GF68cUXKScnh+644w66//77yQADsG6xZZvIGYMeMkrnZkoplpQqIwc6eodoaXn0vsXnZJpkygFXduWFMUQzSOT4fTnTRE5+VlKLHPVvqK/dETTkU00fpWekUeWqYiV9tb5ColWxbG3Ax9LZ2KuInZ0N2gwubrC4eUediJ3KVSVR7/MEQDxIGuHj8Xjotttuo61bt9KDDz447fbx8XG66aabqLS0lHbu3Ent7e30vve9j4xGI/37v/97XI4ZxB97ton6h2MQ8ZlY/JEVsaYoN5OyLAbq6Imy8MlS0jADw+5pwmeayOFITs90kcO9XyZLyJNP5Kg4h1ziz1GjOoHPlSeOq0Knek0pmTNj36Orp3VAGxnR1zYo15mzTLThmpUidpasLcPICJByJI3w+cpXviLbhx9+OOTtzz77LB0/fpz++te/UklJCW3cuJG+9rWv0b333ktf/vKXJUoE9Bnxae0JbjgXtYhPin37lX4rZTbq6Jn0kkSDnCzl/15Xh4N8nUOSqppL5Ignh6eQs8jJy6JkhauduHkfj4Q4f7iVOhoChnxazSIuFLFTvmhVUAOdQ3Tc30WZGxsyRrNBjmXNdqVrMzc2BCBVSRrhMxe7du2idevWiehR2bFjh6S+jh07Rps2bQr5c263W5aKwxHdD30QX+zZ7C+JUcQnxYQPU1tup2f2Ni3o+XmcbnJ0DNJQx4BsB9sHqPh8Jz2/81zQ/VjQpJLI0QZvNvdrs68Ch3xyI0vuo6P6dHjI52Kljob6RsSvc+K189R6pls5HmOGdJxmwbP8oqqozOECIBlIGeHT0dERJHoY9TLfNhPsAVKjSSD1sOeYZF7X2PiEjE6IFqlWzq6yrMJOHu849QyMUHH+7BEI97CLHCxu2hWBo+67HIoZNpB0i5FylhbQJhntkBoiJ3A0g6Sv/J2SAyew8wgIdRwED/nkyMpi4XS46OQepYsyNzfkSBMLrdqNlSJ2uG8Rm6YB0BtxFT6f/exn6Zvf/Oas9zlx4gStXr06Zsdw33330T333BMU8amqqorZ7wOLS66/zJejPvYcS1SrujJSMOJTXWIlQ0YatXYNivDhCIZ7aJQc7X5hEyB0WPgEkUaUXWClsrWVZCvNVVZZLllL7PTUzpOUlWOgK/5+LSU7HMFpPtEhQofTV91N/dpt2bmZtO6q5SJ0eMjnYos7LoE/s/+CTD7n45OqsDSi6voypYvylqUJMREeAN0Kn0996lP0/ve/f9b71NbWhvVYbGreu3dv0HWdnZ3abTNhNptlgdTE7hc+w053VIXP+MRESqS6WNjwyZKjFMN9Thrqd1J5v5Ma/nyI+v98WISOd8q4CY4a5BRZqXBZMVlLWNzYReSwwJlp7pM1y0z9Q9H3Wi0GLB644kmN6DSf7JRmfuqEcY6gcFRn6fpyaea32GXeLMTOHFBGRpw72KIdW/mKIq2LcrSmrAOQCsRV+BQVFcmKBlztxSXvXV1dVFysTC9/7rnnyGazUX19fVR+B0jeiA8Ln2iKhWRIdfEMJVXMBAqbqdep4wam0peRTtZiG5WsKidbqV2iNyxwcopsEXcGtmabqak9+s0RY4WjZ1ibe8Xb0SF/dCuNqLSmUBM6XOIdDyMwv2dcGaZ2UVZ9RMVL8kXs1G+rlSaHAIAk9vhwj56+vj7Zcuk69/Nhli9fLj17brjhBhE4t99+Oz3wwAPi6/n85z9Pd999NyI6OiaTJ6sbM2g4ikMyWfQwGRnxET58kmPRoooY2Ve3Add5ZulYzX1icnKzqHhpvqRjrHlZlJOvbB3jPvq/PRfobTdfQqVF0WmUZ8u20PCoV/xD3FE7EUVi0zElfcWrt1Up7WZshdwYcaU25DNeqSLuoswTz6WL8t5GbWRFfpldETuX11JhZXTnrAGQiiSN8PniF79Iv/zlL7XLapUWNyu8+uqrKSMjg5566imp4uLoT3Z2tjQw/OpXvxrHowaJQK7VHNWID/t7mGhHfPhb/MhAaBGjXsdLPeGFgtMs7DPJL7drYkaEjbr1X5dltcxYUeQdm6Dfn+ik1m5H1IQPR3yYPoeLSgvin3ZhEcFl9arQ4U7FE+PK+2rKNEq1mTr7iudPxatLMafZuBxeGgvubiDnoEsTYxuvXyViR6rDEjz6CEAikTTCh/v3zNTDR2XJkiX05z//edGOCSQH+VYzDUVT+PjHCIQb8eGTLLf9V9NLmogJSDnxdVo6ZQay7BayF+VQxUpVyGRrURpV3HA0YqEdfnm+GVd3NXf00+b6SooGqr+qN47Cp7/Toc29unA0YMhnehqVLy/ShA7vc+l5vOBUKvc4ksaCOxu0Ias8Y0ydj1WxohhdlAFIdeEDwHzJt1noTOtQVE9MTJqPaHhglIb7R6aJmEBhw92J1aZ1oeABkyxcSmsLNBGjCRr/lk96sZi4PROrl+TTU6810NjYOBkMGVGZ18Vm8F5/xGIxcI24qfFou9YlmRv3qfCsK7V5IHcntvgjUvGE+/+oXZTVgaRcbr7xOiWyU11fii7KAEQBCB+Q8vCYhKERpWmbGoEZc3tpzOUlr8u/9V/m64OvG/Nf55F9vs4z6qHigRF6Zvd5etof/QmFOdMowoV9F8Fpp+zJtFNe5oyVUPGkbkke/eHlc9Ta5aAl5XkLfjwWPfZsC/WwCIzhkM/WM12a0Gk/26OJVBYQqy/jIZ9KT51EMf7yrK4T/i7KLHwYbiS49oplmjBbTMELgB5IvE9cMGfO/yhdLfvnP/1H5PbDwOUZp5xhNz2xr5HG3GM0MUMVUzhkmAxksBjJl55O+UtyqaTcHuSh0fZzs8QrkqyUFWRLK4AL7X1RET6MLcdC3f5J39GARU1v26A25JPNyaqhm9N9VXUlmtDhaFosh3xGAg9cVcUO+4wYrgxjYcZiZ9mmqkVtdAiA3sD/riRkgjI0M2wa19eC2RmfkI0xy0w5hTYyWowiXoxmZWswG8mY6d/KZUPQ7cp1ymI/yNCIix56Yh/ddut6qlsSvWGeiQSbZdcszafjF/rpys0UNZ9PV+9ktdR84LRh41F1yGeb5n9hOLKmzr3ihn2JJDz5uE/ubhCx03yiU6us41ERLHZWXFK9KENJAQAQPkkHn3jX0/Oyf913f0UGC7qwzkX/kIu++F+76bKr1lBNxcKFyrhqbk6BBoazsaa2gHYebacBxyjl2hY+Dd1uzaTj5zulKi7cirgxzxg1n+qixsOtdP5IK3U29AaZvWWo5vpyWrq+gmwJUC021WN0au8FETs80oKjtSwouaMzi51Vly6VQaUAgMUFER+Q8nDKhkWKY+qIhQVWdSV6A8OFsqo6T8ZXnG/tpYtsC6/uyrVaZGba4LBbfFczDvls6tfGQfBoiDGPkppkr4s64JMXN+tbrCGf4eIZ9WpdlM8fahHfEVO5qpjquIvyZTUpM6MMgGQFwgekPCxQuLJrMFrCx2+YjVcDw8WCGz+urMqjhtY+uqguGsJHiRqxzydQ+HAFnOrT4fSVVMH5YXGjDvmsXF2SkN4XjkqdO9QiYufsgWati3JpTYEyMmJbDdmLEsNMDQCA8AE6ocBuIcdIdCM+GemJYZaNJeuXFdJjL5ymUbeXMs3GBXdv5iBZe+cQZfBICL/QUauZGI6GrLtqhYidJTzkM3fhKbZYwJEcTl/JyIi9jeQeVUzVBRXcRXkZ1W+roYIKdFEGIBFJvK9PAMSAotxMOn5hIMrCJ7UjPsy6ZQX02PNEDS29VL9s5mG/s+EaGqW+hm7qbeimouPttHPXeWVqOBvOzQZatqlSGgdyVIcNyonahZjbIPCAUhY7J3c3ag0nc4uttPnNSmPBourFH1IKAIgMCB+gCwrtmeQY7hAPyUJPTBMTE7oRPrZsMy0ts9HZ5vCED4uDgZY+6mtUhE5vYzeN9Ew2DuR6xPSCbNpy5XIRO5UrixO6Tw3/vbSd7VZGRuxskLScGpm65KY1Ina40zPEDgDJA4QP0AWFuZkyg2pk1EM5WQurpBnXicdHZePKIvrjK+fJ7R0jszH4I2N00CkCRxE6XdTX1BvUJ8mUY6aytVVUUFMk60T/ELX0DNLV776YEhXVYK12UR7oUoQbV2BtetNqETtVq0sSpi8QACAyIHyAblJdDBucFyp89OTxYTatKKLHXzpH5xq7qcRoUASOP3Xl7J/so8MVVrkV+ZTvFzkFS4sou9AaFA3pOptGR853kndsnIxRGIURTbgZoip2elsHtO7b7DliscNl6PGc4QUAiA4QPkAXFNot0upxYGiUKortC3qsVPb4cKrK0TMiAz37O4dooEPZlp/soGO7z9OxgBEdFlsmVWyopvylLHSKKa+6YM7xG/n2TOKAWVf/KFUU5VC8GewekhTWsdfOaz2CDKYMqcSSLsobKxNypAgAYP7gfzTQBRxdsFvNInwWiubxSdJUF4914IGdLG5k2zEpcgZ7hmlifPr8sQxTBrmyTLRy01IqXlZCBbXFlJWXHbG3Jd+m9LDp6HPGTfiwT+fE7gY68dp5ajnVJddx2mrFxdVKF+XN1QnV9RkAEF0gfIBuKM7LlC7E0evcnJ6wHhWnw6WJm/6OIRrwb/nyyAzzstiwW76imPJKbJRXapVtrn/rSSPpfm3ZXEPVy+dX3cVYzEbKshipI2DUxGIwOsRdlBsljXXhaLtick9PE4M1i52VlyyhzBx0UQZAD0D4AN1QkpdFxxsXXtKupbriGPGZKSXF0Rs243IH4anwbChupFeyIZ9yS22UV2KlvFKbTCpncTNbc0CO06yoyqXTF7po7QKED5Nvz6KOvtgLH/eoh87s83dRPtyiRbJ4eCmLndWX1VC2PTH7BAEAYgeED9CV8Nn5RrsIl/QF+HPG/akuQ4wjPpKS6hqalo7iLXtTQqWkOEXDgiY3MGrjFza2wuwFVSJdUldCjzx7ioZG3GTNnn90pMCeTW3d0empNBXumnzuYLPWRZkH+TJlywqVLspba8hWGH9vEQAgfkD4AN1Qkp8laSru4KyOT5gPLJzY2rIQ8bSQlFR2biaVLy8WYTNV4GTZuDtybCJRG1cU0W9eOEMnG7vokjVV836cgtwseuNMW9Qqu8a94zLyQroo72sSwcgUVeX5R0bUUn6ZbcG/BwCQGkD4AF0JH6afp40vSPhMhO3vkZRU70hAtCZA4HSGn5JSoza8NVniY7y1mAy0YXkhnWzopIvrK+ctsDjiw9nCzj4nVRbPb4YVv65NxztE7Jza00ijw265nl8rbizIVVnF1fnzemwAQGoD4QN0NaXdZEinfoeTairmf1LkqFFgKTunV0JVSM2akrIYFTGjChvVcxOFlFQs2VJfSvtPdlFHzxCVFc0vipKfqwjQtp6RiIQPj7loPdOldFHe1aBFxKzcCfoapddOaW0huigDAGYFwgfoakp7cX4W9Q0qYwdmS0GNe8bIM+Imj9NDHqdb2R/1yLa7qYdy2vvpv7/wlIgddYzBTCkpReAE+G1KbTFNScWSldV5lGc107HzHfMWPtz9mUdhsPCZC34vOht7tcaCbOhm+PXbvKNOxE7lqhKp0AIAgHCA8EkypJ0+Vcv+oRfOULoR/UYiwdo9RH1ne+hYn5O8Tr+wCRA1InKcHvKNKwbmmTBxxKJ7iOyFOVISPbVCKp4pqViLx8vWlNFf9zfRlRfVkmnKCItwKcjNptbu4Rlv72kZ0MROX/ugXGfOMtGGa1aK2Fmytixho2IAgMQGwifZ8BE10XrZbXpob7yPJinh2MDxo63B12WkkznbTKZsM+UU2ciUZSZTlkkua/u8zTbRydY+aukboi/dvV2XJ9+ta0vp6T2NdPpCN61dXjavxyjKy6bj5zqCruPo2fGditjputAn13GJ/Zrty0TssMA0JPBAUwBAcgDhk2ykEdXQAdld99GPI+ITIc2dQ/TcgWbacfUays3P0URNhskQdurpjMtDGV6PLkUPk2e1UN3SfDp6tmPewqcwL4eGR73U1tJPLYeViqy2M91yG09rX3npEhE7yy+qSsnIGQAgfkD4JBl8cs6ndtlfvWUJGSyWeB9SUlE8MEpPNfYTFeRQbnn+vMvZM3QqelS2ryunn/3xKHX2DlFJQQQGZZ+PhjoHyXmshfKPttLDu85JFJM9OrUbK2nN9lpacfESsmRzMhEAAKIPhA/QFfl2i1R2scF56TyFDzcwNOjcTLumpkBMzkfOtNOb5hA+3lEPdZ5qp47jrdR5olWb6M7SJqcqj7bfWE+rtywVwzIAAMQaCB+gK9icW1qQTb0D8x+ZwBEfg0HfER9u3rh9fTn9ZfcF2r6phjLNxqCy8/7mXuo4oQid3oZuuY5hz1TV5hoqra+gAz2DlF2cRRe9aXUcnwkAQG9A+ADdUV6YTefbhub98+PjE2RI0sns0WTr2jL6y+5GOnaug9ZWFlDHiTbqPNFGHSdbyeNvKMgprIKaIiqpq6DSugrKq8qnNH/zx+bXz9OFtt44PwsAgN6A8AG6o6Iwh/ad6Jz3zK6xiQkyJuhk9sXAOeSi7qZ+6m7up5ruITr7369Rw7BLuz0rL5sqti2RqE7xylIxkIeiKC+HDp5spRGXl7JhYAYALBIQPkB3VBRlS/fl/iGnjE+IlPFxH1nMqR/x4XEa3E+HBU5XU58mdqbOEGPxaF1aRLWbl0pUx1piD6tCrqQgR6u0W70E4yUAAIsDhA/QHeVFygm3p39kXsKHZ3UZM1Lnvw4P+extG9SEjbrlyfBBpBHlFVup4pJqKqzKo6LqPBkE+ujOBnJ4iFZcXR9RN2qel2YyZlAThA8AYBFJnU9vAMKE0yq5OWbqGRihVfN41caT1NzMgz1ZzEwVONwZeeo8sZy8LGkYWOQXOMXVeVRQkRuyp871YxP00yeOUnuPg8qL7GEfD4uk4vwcutAxf78VAABECoQP0G26q7tv5pEJc5azJ3AfH+mV0+cMFjhNfZK2GvOOB92X++VUrCymoup8TeQUVeZRpjW0LycU9TUFVJKXRa+faI1I+DAl+VY626w0LgQAgMUAwgfokqpiK718uE1EQqTDQjlykijCRzMaT4niuJ2eoPvx6AcRNf70lLrlyM5Ch6Vyi4DrLq6iR587Jf2R8u3K9PVw4OaHB0600OCwm+w54YstAACYLxA+QJdUFueQ0+WlkVEP5cxQdTRrqmuRy9nZaNzdMl3gTDMaZ6RRQXkuFW2qDBI4ucXWmE4wv3h1CT21s0FEzJsuWxn2z6ldnxs7HLRheVHMjg8AAFQgfIBuIz5Md//wPIRP7CI+nIrqi9BoHJimyi+1yayrxcZoSKfrNlfRE6+cpy3rqsmWHV4X5pwsE2VnmqixHcIHALA4QPgAXcLjFrLMBurqG6aaioJ5NDBMj5rRuCtA5LDRWO1yrMLpqFo2GgekqWYyGseTy9eV0TN7L9CB4y10zSXLw/oZTrOVFlpF+AAAwGIA4QN0CZ9wq0qsInwiZYyFT5hVXZNG48k+OLydyWhcuaok2IcTodE4nphNBrr2oirp5nzJmqqwI2mlBTbae/SCRNIydNwYEgCwOCSF8GlsbKSvfe1r9MILL1BHRweVl5fTe9/7Xvrc5z5HJtPkFOcjR47Q3XffTfv27aOioiL62Mc+Rp/5zGfieuwgcakusdKuox0R/xx7fIwhIj5OhysoPRWu0biYU1XVeZSdm7lgo3G8uXJjBT1/oFmiPlddvCysnykrspJ3bILaeka0FCQAAOha+Jw8eVKaxv30pz+l5cuX09GjR+mDH/wgjYyM0P/7f/9P7uNwOOiGG26g66+/nn7yk5/QG2+8QXfeeSfl5ubShz70oXg/BZCgwue5fU1icGafSbgRnHG3l0Y7HHTo+VMB5eL9NDI4i9E4IIqTWxRbo3E8yTRz1KeSnt5zgTbXV4YV9SnOt0r35/NtgxA+AICYkxTC581vfrMsldraWjp16hT9+Mc/1oTPI488Qh6Ph37xi19IFGjNmjV06NAh+va3vw3hA2YUPkxH9yBV5GaTy+Ei95CLXMOjspX9IWXfNcyXR8k15KJi7zgd3t1AhwONxiU2fz+cvLgbjePNVZsq6YXXW2j/sWa6OgyvD/ulivNyqKHNQVdtXJRDBADomKQQPqEYHByk/PzJ+T67du2iK6+8Mij1tWPHDvrmN79J/f39lJeXF/Jx3G63LBWOHCUybHw9SIoIPPLBxyiNz7pgvq8mlXrH6fWd5+j1Oe6ZYTKQxWohe3ketTuctKquhNZtVCI5hZV5kr4Ck1Gf6y+uoj/taqSL6ivDqvAqK7LRuZYevIQAgJiTlJ/WZ8+epR/84AdatIdh709NTU3Q/UpKSrTbZhI+999/P33lK1+hZMJCSmmzvbyE0mAGXRCd/U6aSE+nyupCstgyyZxjEYFjtmaS2erfz7GQwaxUULk8XvrZ/+2mNW9ZQ+tXoO/MTFy1sYJefL2F9r7RRNeH0denvMgmk9r7HC7Kt4VXCg8AAEknfD772c9KRGY2Tpw4QatXr9Yut7a2StrrtttuE5/PQrnvvvvonnvuCYr4VFVVUaJiyLTQR//no7KfYTYnvRk23nAF0gsHWuhtb7ssrNeSJ7Mzi93AMNngCq8dW5bQ7186S5vqKuYcBssRH4Z9PhA+AICUFT6f+tSn6P3vf/+s92E/j0pbWxtdc801tG3bNvrZz34WdL/S0lLq7OwMuk69zLfNhNlslpUs8MnZYME34mixtNRGLs8YDQ65KNeWGVYPHyZRRlYkMpevK6cXDjTTrsMX6C1X1s963yyLifJtmXSudVC6QAMAQEoKHy455xUOHOlh0bN582Z66KGHKH1Kimfr1q1S3u71esloVNISzz33HK1atWrGNBcAS0oVgzNPFg9H+HAPH7VTMZgdfo3+/vIa+u+nT1Jb9+CcA0zLiux0pnkALysAIKYkxac3i56rr76aqqurxdfT3d0tvh1eKu9+97vF2HzXXXfRsWPH6LHHHqPvfe97QWksAKaSZTFScW4mdfROGQkxh/BBxCc8Nq8uocqiHHr1YIO0ApiNimK7eK6GpvQ9AgAA3Qkfjtywofn555+nyspKKisr05aK3W6nZ599lhoaGiQqxGm0L37xiyhlB3NSU26jzp7wqvm4uzCDiE/4k9tvuXIZdfQM0Zmm2au2KkqUiBCnuwAAQNfCh31A/G0x1Apk/fr19Morr5DL5aKWlha6995743bMIHmoKbNT98AIeaaMkAgFUl2Rs6o6j9bU5NPOQw3a6xcKa5aZcq0WOtOCdBcAQOfCB4BYR3xYQ3eGke5Szc1Gg/4aEy6Et165nIZHPVKyPhvlxXY63dS/aMcFANAfSdnHB4BoUlqQTRZTBp2+0E05WbOPrugbdMo21KwuMDMl+Vl05YZyevVIk/TsYW9VKHIyTXT8nOLzsc7xXgAAwHyA8AG6h30oNWU2OnauQ1Y4mIwQPpFy42VL6W8HW+l3fz0y5337h9wQPgCAmIBPbwCI6O+3T/aLmot/vHYFUl3zgKM8H3v7hjnvV7c0X5ujBgAA0QYRHwCIZCr4Dz55NV6LGLOyKg+vMwAgriDiAwAAAADdAOEDAAAAAN0A4QMAAAAA3QDhAwAAAADdAOEDAAAAAN0A4QMAAAAA3QDhAwAAAADdAOEDAAAAAN0A4QMAAAAA3QDhAwAAAADdAOEDAAAAAN0A4QMAAAAA3QDhAwAAAADdAOEDAAAAAN0A4QMAAAAA3QDhAwAAAADdAOEDAAAAAN0A4QMAAAAA3QDhAwAAAADdAOEDAAAAAN0A4QMAAAAA3QDhAwAAAADdAOEDAAAAAN0A4QMAAAAA3QDhAwAAAADdAOEDAAAAAN0A4QMAAAAA3QDhAwAAAADdAOEDAAAAAN0A4QMAAAAA3QDhAwAAAADdAOEDAAAAAN2QNMLnH/7hH6i6uposFguVlZXR7bffTm1tbUH3OXLkCF1xxRVyn6qqKnrggQfidrwAAAAASDySRvhcc8019Jvf/IZOnTpFv/vd7+jcuXP09re/Xbvd4XDQDTfcQEuWLKEDBw7Qt771Lfryl79MP/vZz+J63AAAAABIHAyUJHzyk5/U9lncfPazn6VbbrmFvF4vGY1GeuSRR8jj8dAvfvELMplMtGbNGjp06BB9+9vfpg996ENxPXYAAAAAJAZJE/EJpK+vT4TOtm3bRPQwu3btoiuvvFJEj8qOHTskQtTf3x/HowUAAABAopBUwufee++l7OxsKigooKamJnriiSe02zo6OqikpCTo/uplvm0m3G63pMkCFwAAAABSk7gKH05XpaWlzbpOnjyp3f/Tn/40HTx4kJ599lnKyMig973vfeTz+RZ0DPfffz/Z7XZtsSkaAAAAAKlJmm+hymEBdHd3U29v76z3qa2tDUpfqbS0tIhI2blzJ23dulVEEEdr/vCHP2j3efHFF+naa6+V1FheXt6MER9eKvwY/LiDg4Nks9kW9PwAAACAZMbn85F33CP7xgyTBCQSFT5/cwBjrvN3XM3NRUVFsubDxMSEbFXRwuLnc5/7nGZ2Zp577jlatWrVjKKHMZvNsgAAAAAQDAsdkyG1zpFJ4fHZs2cP/ed//qdUaV24cIFeeOEFete73kXLli0TwcO8+93vlsjQXXfdRceOHaPHHnuMvve979E999wT78MHAAAAQIKQFMInKyuLfv/739N1110nERwWN+vXr6eXXnpJi9ZweIu9Pw0NDbR582b61Kc+RV/84hdRyg4AAACAxPD4JHOOEAAAAADJd/5OiogPAAAAAEA0gPABAAAAgG6A8AEAAACAboDwAQAAAIBugPABAAAAgG6A8AEAAACAboDwAQAAAIBugPABAAAAgG6A8AEAAACAboDwAQAAAIBugPABAAAAgG6A8AEAAACAboDwAQAAAIBugPABAAAAgG6A8AEAAACAboDwAQAAAIBugPABAAAAgG6A8AEAAACAboDwAQAAAIBugPABAAAAgG6A8AEAAACAboDwAQAAAIBuMMT7ABINn88nW4fDEe9DAQAAAECYqOdt9Tw+ExA+UxgaGpJtVVVVuK81AAAAABLoPG6322e8Pc03lzTSGRMTE9TW1kZWq5XS0tLifTgpq8pZWDY3N5PNZov34egWvA/xB+9B/MF7kDrvA8sZFj3l5eWUnj6zkwcRnynwi1VZWTmvFx1EBv9xQ/jEH7wP8QfvQfzBe5Aa78NskR4VmJsBAAAAoBsgfAAAAACgGyB8wKJjNpvpS1/6kmxB/MD7EH/wHsQfvAf6ex9gbgYAAACAbkDEBwAAAAC6AcIHAAAAALoBwgcAAAAAugHCBwAAAAC6AcIHLDo//OEPaenSpWSxWGjLli20d+9evAsx4v7776dLLrlEOpEXFxfTLbfcQqdOnQq6j8vlorvvvpsKCgooJyeH3va2t1FnZyfekxjxjW98Q7rCf+ITn8B7sIi0trbSe9/7Xvk7z8zMpHXr1tH+/fuDuv5+8YtfpLKyMrn9+uuvpzNnzizmIaY84+Pj9IUvfIFqamrkNV62bBl97WtfC5qttRjvA4QPWFQee+wxuueee6Rs8fXXX6cNGzbQjh07qKurC+9EDHjppZdE1OzevZuee+458nq9dMMNN9DIyIh2n09+8pP05JNP0m9/+1u5P49sufXWW/F+xIB9+/bRT3/6U1q/fn3Q9XgPYkt/fz9dfvnlZDQa6S9/+QsdP36c/uM//oPy8vK0+zzwwAP0/e9/n37yk5/Qnj17KDs7Wz6b+IsBiA7f/OY36cc//jH953/+J504cUIu8+v+gx/8YHHfB57VBcBicemll/ruvvtu7fL4+LivvLzcd//99+NNWAS6urr4q5XvpZdekssDAwM+o9Ho++1vf6vd58SJE3KfXbt24T2JIkNDQ74VK1b4nnvuOd9VV13l+/jHP473YJG49957fdu3b5/x9omJCV9paanvW9/6lnYd/98wm82+X/3qV4t0lKnPTTfd5LvzzjuDrrv11lt973nPexb1fUDEBywaHo+HDhw4IKHLwNlofHnXrl14JxaBwcFB2ebn58uW3w+OAgW+J6tXr6bq6mq8J1GGI2833XRT0GuN92Bx+OMf/0gXX3wx3XbbbZLy3bRpE/385z/Xbm9oaKCOjo6g94ZnPnEqHp9N0WPbtm30/PPP0+nTp+Xy4cOH6dVXX6Ubb7xxUd8HDCkFi0ZPT4/keEtKSoKu58snT57EOxFjJiYmxFfCIf+1a9fKdfwhYzKZKDc3d9p7wreB6PDrX/9aUruc6poK3oPYc/78eUmxcJr9X//1X+V9+Jd/+Rf527/jjju0v/VQn034fxA9PvvZz8oUdv5ylZGRIeeDr3/96/Se97xHbl+s9wHCBwAdRRyOHj0q37DA4tHc3Ewf//jHxWPFhn4QH9HPEZ9///d/l8sc8eH/C+wjYeEDFoff/OY39Mgjj9Cjjz5Ka9asoUOHDsmXsfLy8kV9H5DqAotGYWGhqPypFUN8ubS0FO9EDPnoRz9KTz31FL344otUWVmpXc+vO6cgBwYG8J7ECE4nsnn/oosuIoPBIItN5Gzg5H3+Nov3ILZwhVB9fX3QdXV1ddTU1CT76ucPPptiy6c//WmJ+rzzne+Uqrrbb79djP1cfbqY7wOED1g0OKy8efNmyfEGfhPjy1u3bsU7EQO4NJRFz+OPP04vvPCClJEGwu8HV7oEvidc7s4nBLwn0eG6666jN954Q77dqoujDxzeV/fxHsQWTu9ObePAPpMlS5bIPv+/4BNr4P8DTslwVRH+H0QPp9Mpvs5A+MswnwcW9X2Imk0agDD49a9/LQ79hx9+2Hf8+HHfhz70IV9ubq6vo6MDr18M+PCHP+yz2+2+v/3tb7729nZtOZ1O7T7//M//7Kuurva98MILvv379/u2bt0qC8SOwKouvAexZ+/evT6DweD7+te/7jtz5ozvkUce8WVlZfn+93//V7vPN77xDfkseuKJJ3xHjhzx3Xzzzb6amhrf6OjoIhyhPrjjjjt8FRUVvqeeesrX0NDg+/3vf+8rLCz0feYzn1nU9wHCByw6P/jBD+REazKZpLx99+7deBdiBH+3CbUeeugh7T78gfKRj3zEl5eXJyeDt771rSKOwOIJH7wHsefJJ5/0rV27Vr54rV692vezn/0s6HYupf7CF77gKykpkftcd911vlOnTi3CkekHh8Mhf/f8+W+xWHy1tbW+z33ucz63272o70Ma/xO9+BEAAAAAQOICjw8AAAAAdAOEDwAAAAB0A4QPAAAAAHQDhA8AAAAAdAOEDwAAAAB0A4QPAAAAAHQDhA8AAAAAdAOEDwAAAAB0A4QPACCpSUtLk5WbmxuX3//www9rx8CTpgEAiQ2EDwAg6XnooYdk6GQ8eMc73kHt7e0YZglAkmCI9wEAAMBC4WhPcXFxXF7IzMxMWSaTKS6/HwAQGYj4AAAShsbGRi1tFLiuvvrqiB7ny1/+Mm3cuJF+8YtfUHV1NeXk5NBHPvIRGh8fpwceeIBKS0tFKH39618P+jn+XT/96U/pLW95C2VlZVFdXR3t2rWLzp49K8eQnZ1N27Zto3PnzkX5mQMAFgsIHwBAwlBVVSVpI3UdPHiQCgoK6Morr4z4sVic/OUvf6Gnn36afvWrX9GDDz5IN910E7W0tNBLL71E3/zmN+nzn/887dmzJ+jnvva1r9H73vc+OnToEK1evZre/e530z/90z/RfffdR/v37yee6/zRj340is8aALCYINUFAEgYMjIyJBrDuFwuuuWWW8Q7wxGcSJmYmJCIj9Vqpfr6errmmmvo1KlT9Oc//5nS09Np1apVIn5efPFF2rJli/ZzH/jAB+gf//EfZf/ee++V3/+FL3yBduzYIdd9/OMfl/sAAJITCB8AQEJy55130tDQED333HMiVCJl6dKlInpUSkpKRFgFPhZf19XVFfRz69evD7qdWbduXdB1LMocDgfZbLaIjwsAEF8gfAAACce//du/0TPPPEN79+4NEi+RYDQap/l3Ql3HkaGZfo5vn+m6qT8HAEgOIHwAAAnF7373O/rqV78q/pxly5bF+3AAACkGhA8AIGE4evSoGIvZW7NmzRrq6OiQ67lUPD8/P96HBwBIAVDVBQBIGLhqyul0SqqrrKxMW7feemu8Dw0AkCKk+bg2EwAAkhT23Dz++ONSARZPuM8P9w767ne/G9fjAADMDiI+AICk513vehdVVlbG5Xc/8sgj0iDxlVdeicvvBwBEBiI+AICkhrsqM1yqXlNTs+i/n0vuOzs7tdEZhYWFi34MAIDwgfABAAAAgG5AqgsAAAAAugHCBwAAAAC6AcIHAAAAALoBwgcAAAAAugHCBwAAAAC6AcIHAAAAALoBwgcAAAAAugHCBwAAAACkF/4/XUdasjZ7ImMAAAAASUVORK5CYII=", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "x,weights = source.sample([11],\"simpson\")\n", "O2,D2,wl,n_func_enviroment,meta_data = system(x,[\"light_source\",\"lens1\",\"lens2\",\"detector\"])\n", "dit.plotting.system2D.plot(system,meta_data)\n" ] } ], "metadata": { "kernelspec": { "display_name": "working", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.12.0" } }, "nbformat": 4, "nbformat_minor": 5 }