From 135fd13b7cc5dba7143a02b050b12c1a025ea57b Mon Sep 17 00:00:00 2001 From: Ardavan Oskooi Date: Fri, 29 Apr 2022 19:00:23 -0700 Subject: [PATCH 1/2] unit test for near-to-far field transformation with symmetries --- python/tests/test_antenna_radiation.py | 265 +++++++++++++++++++++---- 1 file changed, 225 insertions(+), 40 deletions(-) diff --git a/python/tests/test_antenna_radiation.py b/python/tests/test_antenna_radiation.py index 3eeca002c..7194a1b30 100644 --- a/python/tests/test_antenna_radiation.py +++ b/python/tests/test_antenna_radiation.py @@ -2,16 +2,185 @@ import math import numpy as np import unittest +from utils import ApproxComparisonTestCase -## compute the Poynting flux of an Ez-polarized dipole point source -## from the fields in 3 arrangements: -## (1) bounding box of the near fields -## (2) bounding circle of the far fields -## (3) bounding box of the far fields +class TestAntennaRadiation(ApproxComparisonTestCase): -class TestAntennaRadiation(unittest.TestCase): + @classmethod + def setUp(cls): + cls.resolution = 100 # pixels/μm - def test_farfield(self): + cls.h = 1.125 # height of point source above ground plane + cls.n = 1.2 # refractive index of surrounding medium + + cls.src_cmpt = mp.Ez + cls.wvl = 0.65 + + cls.npts = 50 # number of points in [0,pi/2) range of angles + cls.angles = 0.5*math.pi/cls.npts*np.arange(cls.npts) + cls.r = 1000*cls.wvl # radius of far-field hemicircle + + + def radial_flux(self,sim,nearfield_box,r): + E = np.zeros((self.npts,3),dtype=np.complex128) + H = np.zeros((self.npts,3),dtype=np.complex128) + for n in range(self.npts): + ff = sim.get_farfield(nearfield_box, + mp.Vector3(r*math.sin(self.angles[n]), + r*math.cos(self.angles[n]))) + E[n,:] = [np.conj(ff[j]) for j in range(3)] + H[n,:] = [ff[j+3] for j in range(3)] + + Px = np.real(E[:,1]*H[:,2]-E[:,2]*H[:,1]) # Ey*Hz-Ez*Hy + Py = np.real(E[:,2]*H[:,0]-E[:,0]*H[:,2]) # Ez*Hx-Ex*Hz + Pr = np.sqrt(np.square(Px)+np.square(Py)) + + return Pr + + + def free_space_radiation(self): + sxy = 4 + dpml = 1 + cell_size = mp.Vector3(sxy+2*dpml,sxy+2*dpml) + + pml_layers = [mp.PML(dpml)] + + fcen = 1/self.wvl + + sources = [mp.Source(src=mp.GaussianSource(fcen,fwidth=0.2*fcen), + center=mp.Vector3(), + component=self.src_cmpt)] + + if self.src_cmpt == mp.Hz: + symmetries = [mp.Mirror(mp.X,phase=-1), + mp.Mirror(mp.Y,phase=-1)] + elif self.src_cmpt == mp.Ez: + symmetries = [mp.Mirror(mp.X,phase=+1), + mp.Mirror(mp.Y,phase=+1)] + else: + symmetries = [] + + sim = mp.Simulation(cell_size=cell_size, + resolution=self.resolution, + sources=sources, + symmetries=symmetries, + boundary_layers=pml_layers, + default_material=mp.Medium(index=self.n)) + + nearfield_box = sim.add_near2far(fcen, + 0, + 1, + mp.Near2FarRegion(center=mp.Vector3(0,+0.5*sxy), + size=mp.Vector3(sxy,0)), + mp.Near2FarRegion(center=mp.Vector3(0,-0.5*sxy), + size=mp.Vector3(sxy,0), + weight=-1), + mp.Near2FarRegion(center=mp.Vector3(+0.5*sxy,0), + size=mp.Vector3(0,sxy)), + mp.Near2FarRegion(center=mp.Vector3(-0.5*sxy,0), + size=mp.Vector3(0,sxy), + weight=-1)) + + sim.run(until_after_sources=mp.stop_when_dft_decayed()) + + Pr = self.radial_flux(sim,nearfield_box,self.r) + + return Pr + + + def pec_ground_plane_radiation(self): + L = 8.0 # length of non-PML region + dpml = 1.0 # thickness of PML + sxy = dpml+L+dpml + cell_size = mp.Vector3(sxy,sxy,0) + + boundary_layers = [mp.PML(dpml)] + + fcen = 1/self.wvl + + # The near-to-far field transformation feature only supports + # homogeneous media which means it cannot explicitly take into + # account the ground plane. As a workaround, we use two antennas + # of _opposite_ sign surrounded by a single near2far box which + # encloses both antennas. We then use an odd mirror symmetry to + # cut the computational cell in half which is effectively + # equivalent to a PEC boundary condition on one side. + # Note: This setup means that the radiation pattern can only + # be measured in the top half above the dipole. + sources = [mp.Source(src=mp.GaussianSource(fcen,fwidth=0.2*fcen), + component=self.src_cmpt, + center=mp.Vector3(0,+self.h)), + mp.Source(src=mp.GaussianSource(fcen,fwidth=0.2*fcen), + component=self.src_cmpt, + center=mp.Vector3(0,-self.h), + amplitude=-1 if self.src_cmpt==mp.Ez else +1)] + + symmetries = [mp.Mirror(direction=mp.X, + phase=+1 if self.src_cmpt==mp.Ez else -1), + mp.Mirror(direction=mp.Y, + phase=-1 if self.src_cmpt==mp.Ez else +1)] + + sim = mp.Simulation(resolution=self.resolution, + cell_size=cell_size, + boundary_layers=boundary_layers, + sources=sources, + symmetries=symmetries, + default_material=mp.Medium(index=self.n)) + + nearfield_box = sim.add_near2far(fcen, + 0, + 1, + mp.Near2FarRegion(center=mp.Vector3(0,2*self.h), + size=mp.Vector3(2*self.h,0)), + mp.Near2FarRegion(center=mp.Vector3(0,-2*self.h), + size=mp.Vector3(2*self.h,0), + weight=-1), + mp.Near2FarRegion(center=mp.Vector3(self.h,0), + size=mp.Vector3(0,4*self.h)), + mp.Near2FarRegion(center=mp.Vector3(-self.h,0), + size=mp.Vector3(0,4*self.h), + weight=-1)) + + sim.run(until_after_sources=mp.stop_when_dft_decayed()) + + Pr = self.radial_flux(sim,nearfield_box,self.r) + + return Pr + + + def test_pec_ground_plane(self): + """Unit test for near-to-far field transformation and symmetries. + + Verifies that the radiation pattern for a point dipole source a + given height above a perfect-electric conductor (PEC) ground plane + agrees with the theoretical result. + """ + Pr_fsp = self.free_space_radiation() + Pr_pec = self.pec_ground_plane_radiation() + + k = 2*np.pi/(self.wvl/self.n) # wavevector in medium + Pr_theory = np.zeros(self.npts,) + for i,ang in enumerate(self.angles): + Pr_theory[i] = Pr_fsp[i] * 2*np.sin(k*self.h*np.cos(ang)) + + Pr_pec_norm = Pr_pec/np.max(Pr_pec) + Pr_theory_norm = (Pr_theory/max(Pr_theory))**2 + + tol = 0.02 + self.assertClose(Pr_pec_norm, Pr_theory_norm, epsilon=tol) + + + def test_poynting_theorem(self): + """Unit test for near-to-far field transformation in 2d. + + Verifies that the Poynting flux of an Ez-polarized point + dipole source in vacuum is independent of the shape of the + enclosing measurement box due to Poynting's theorem by + considering three arrangements: + (1) bounding box of thenear fields, + (2) bounding circle of the far fields, and + (3) bounding box of the far fields. + """ resolution = 50 sxy = 4 dpml = 1 @@ -22,58 +191,73 @@ def test_farfield(self): fcen = 1.0 df = 0.4 - sources = mp.Source(src=mp.GaussianSource(fcen,fwidth=df), - center=mp.Vector3(), - component=mp.Ez) + sources = [mp.Source(src=mp.GaussianSource(fcen,fwidth=df), + center=mp.Vector3(), + component=mp.Ez)] symmetries = [mp.Mirror(mp.X), mp.Mirror(mp.Y)] sim = mp.Simulation(cell_size=cell, resolution=resolution, - sources=[sources], + sources=sources, symmetries=symmetries, boundary_layers=[pml_layers]) - nearfield_box = sim.add_near2far(fcen, 0, 1, - mp.Near2FarRegion(mp.Vector3(y=0.5*sxy), size=mp.Vector3(sxy)), - mp.Near2FarRegion(mp.Vector3(y=-0.5*sxy), size=mp.Vector3(sxy), weight=-1), - mp.Near2FarRegion(mp.Vector3(0.5*sxy), size=mp.Vector3(y=sxy)), - mp.Near2FarRegion(mp.Vector3(-0.5*sxy), size=mp.Vector3(y=sxy), weight=-1), - decimation_factor=20) + nearfield_box = sim.add_near2far(fcen, + 0, + 1, + mp.Near2FarRegion(mp.Vector3(y=0.5*sxy), + size=mp.Vector3(sxy)), + mp.Near2FarRegion(mp.Vector3(y=-0.5*sxy), + size=mp.Vector3(sxy), + weight=-1), + mp.Near2FarRegion(mp.Vector3(0.5*sxy), + size=mp.Vector3(y=sxy)), + mp.Near2FarRegion(mp.Vector3(-0.5*sxy), + size=mp.Vector3(y=sxy), + weight=-1)) - flux_box = sim.add_flux(fcen, 0, 1, - mp.FluxRegion(mp.Vector3(y=0.5*sxy), size=mp.Vector3(sxy)), - mp.FluxRegion(mp.Vector3(y=-0.5*sxy), size=mp.Vector3(sxy), weight=-1), - mp.FluxRegion(mp.Vector3(0.5*sxy), size=mp.Vector3(y=sxy)), - mp.FluxRegion(mp.Vector3(-0.5*sxy), size=mp.Vector3(y=sxy), weight=-1)) + flux_box = sim.add_flux(fcen, + 0, + 1, + mp.FluxRegion(mp.Vector3(y=0.5*sxy), + size=mp.Vector3(sxy)), + mp.FluxRegion(mp.Vector3(y=-0.5*sxy), + size=mp.Vector3(sxy), + weight=-1), + mp.FluxRegion(mp.Vector3(0.5*sxy), + size=mp.Vector3(y=sxy)), + mp.FluxRegion(mp.Vector3(-0.5*sxy), + size=mp.Vector3(y=sxy), + weight=-1)) sim.run(until_after_sources=mp.stop_when_fields_decayed(50, mp.Ez, mp.Vector3(), 1e-8)) near_flux = mp.get_fluxes(flux_box)[0] r = 1000/fcen # radius of far field circle - npts = 100 # number of points in [0,2*pi) range of angles - E = np.zeros((npts,3),dtype=np.complex128) - H = np.zeros((npts,3),dtype=np.complex128) - for n in range(npts): - ff = sim.get_farfield(nearfield_box, - mp.Vector3(r*math.cos(2*math.pi*n/npts), - r*math.sin(2*math.pi*n/npts))) - E[n,:] = [np.conj(ff[j]) for j in range(3)] - H[n,:] = [ff[j+3] for j in range(3)] - - Px = np.real(E[:,1]*H[:,2]-E[:,2]*H[:,1]) - Py = np.real(E[:,2]*H[:,0]-E[:,0]*H[:,2]) - Pr = np.sqrt(np.square(Px)+np.square(Py)) - far_flux_circle = np.sum(Pr)*2*np.pi*r/len(Pr) + Pr = self.radial_flux(sim,nearfield_box,r) + far_flux_circle = 4*np.sum(Pr)*0.5*np.pi*r/len(Pr) rr = 20/fcen # length of far-field square box res_far = 20 # resolution of far-field square box - far_flux_square = (nearfield_box.flux(mp.Y, mp.Volume(center=mp.Vector3(y=0.5*rr), size=mp.Vector3(rr)), res_far)[0] - - nearfield_box.flux(mp.Y, mp.Volume(center=mp.Vector3(y=-0.5*rr), size=mp.Vector3(rr)), res_far)[0] - + nearfield_box.flux(mp.X, mp.Volume(center=mp.Vector3(0.5*rr), size=mp.Vector3(y=rr)), res_far)[0] - - nearfield_box.flux(mp.X, mp.Volume(center=mp.Vector3(-0.5*rr), size=mp.Vector3(y=rr)), res_far)[0]) + far_flux_square = (nearfield_box.flux(mp.Y, + mp.Volume(center=mp.Vector3(y=0.5*rr), + size=mp.Vector3(rr)), + res_far)[0] - + nearfield_box.flux(mp.Y, + mp.Volume(center=mp.Vector3(y=-0.5*rr), + size=mp.Vector3(rr)), + res_far)[0] + + nearfield_box.flux(mp.X, + mp.Volume(center=mp.Vector3(0.5*rr), + size=mp.Vector3(y=rr)), + res_far)[0] - + nearfield_box.flux(mp.X, + mp.Volume(center=mp.Vector3(-0.5*rr), + size=mp.Vector3(y=rr)), + res_far)[0]) print("flux:, {:.6f}, {:.6f}, {:.6f}".format(near_flux,far_flux_circle,far_flux_square)) @@ -81,5 +265,6 @@ def test_farfield(self): self.assertAlmostEqual(far_flux_circle, far_flux_square, places=2) self.assertAlmostEqual(far_flux_square, near_flux, places=2) + if __name__ == '__main__': unittest.main() From ffcf5dc35abf01ac9e1d0de936644050c95fdf39 Mon Sep 17 00:00:00 2001 From: Ardavan Oskooi Date: Sat, 30 Apr 2022 15:36:29 -0700 Subject: [PATCH 2/2] tutorial for antenna above a PEC ground plane --- .../Near_to_Far_Field_Spectra.md | 265 ++++++++++++++++-- doc/docs/images/antenna_pec_ground_plane.png | Bin 0 -> 85864 bytes python/examples/antenna-radiation.py | 68 +++-- python/examples/antenna_pec_ground_plane.py | 183 ++++++++++++ python/tests/test_antenna_radiation.py | 5 + 5 files changed, 481 insertions(+), 40 deletions(-) create mode 100644 doc/docs/images/antenna_pec_ground_plane.png create mode 100644 python/examples/antenna_pec_ground_plane.py diff --git a/doc/docs/Python_Tutorials/Near_to_Far_Field_Spectra.md b/doc/docs/Python_Tutorials/Near_to_Far_Field_Spectra.md index 6c8099cd0..7bdb01bfd 100644 --- a/doc/docs/Python_Tutorials/Near_to_Far_Field_Spectra.md +++ b/doc/docs/Python_Tutorials/Near_to_Far_Field_Spectra.md @@ -2,14 +2,14 @@ # Near to Far Field Spectra --- -The [near-to-far field transformation](../Python_User_Interface.md#near-to-far-field-spectra) feature is demonstrated using four different examples. There are three steps involved in this type of calculation. First, the "near" surface(s) is defined as a set of surfaces capturing *all* outgoing radiation in the desired direction(s). Second, the simulation is run using a pulsed source (or alternatively, a CW source via the [frequency-domain solver](../Python_User_Interface.md#frequency-domain-solver)) to allow Meep to accumulate the DFT fields on the near surface(s). Third, Meep computes the far fields at any desired points with the option to save the far fields to an HDF5 file. +The [near-to-far field transformation](../Python_User_Interface.md#near-to-far-field-spectra) feature is demonstrated using five different examples. There are three steps involved in this type of calculation. First, the "near" surface(s) is defined as a set of surfaces capturing *all* outgoing radiation in *free space* in the desired direction(s). Second, the simulation is run using a pulsed source (or alternatively, a CW source via the [frequency-domain solver](../Python_User_Interface.md#frequency-domain-solver)) to allow Meep to accumulate the DFT fields on the near surface(s). Third, Meep computes the "far" fields at any desired points with the option to save the far fields to an HDF5 file. [TOC] Radiation Pattern of an Antenna ------------------------------- -In this example, we compute the [radiation pattern](https://en.wikipedia.org/wiki/Radiation_pattern) of an antenna. This involves an electric-current point dipole emitter in vacuum. The source is placed at the center of a 2d cell surrounded by PML. The near fields are obtained on a bounding box defined along the edges of the non-PML region. The far fields are computed in two ways from *closed* surfaces: (1) sides of a square and (2) circumference of a circle, having a length/radius many times larger than the source wavelength and lying beyond the cell. From both the near and far fields, we will also compute the total outgoing Poynting flux and demonstrate that they are equivalent. Results will be shown for three orthogonal polarizations of the input source. +In this example, we compute the [radiation pattern](https://en.wikipedia.org/wiki/Radiation_pattern) of an antenna in free space. This involves computing the far fields of an electric-current point dipole emitter in vacuum. The source is placed at the center of a 2D cell surrounded by PML. The near fields are obtained on a bounding box defined along the edges of the non-PML region. The far fields are computed in two ways from *closed* surfaces: (1) sides of a square and (2) circumference of a circle, having a length/radius many times larger than the source wavelength and lying beyond the cell. From both the near and far fields, we will also compute the total outgoing Poynting flux and demonstrate that they are equivalent. Results will be shown for three orthogonal polarizations of the input source. The simulation geometry is shown in the following schematic. @@ -27,6 +27,7 @@ import math import numpy as np import matplotlib.pyplot as plt + resolution = 50 # pixels/um sxy = 4 @@ -39,8 +40,8 @@ fcen = 1.0 df = 0.4 src_cmpt = mp.Ez sources = [mp.Source(src=mp.GaussianSource(fcen,fwidth=df), - center=mp.Vector3(), - component=src_cmpt)] + center=mp.Vector3(), + component=src_cmpt)] if src_cmpt == mp.Ex: symmetries = [mp.Mirror(mp.X,phase=-1), @@ -59,18 +60,30 @@ sim = mp.Simulation(cell_size=cell, boundary_layers=pml_layers) nearfield_box = sim.add_near2far(fcen, 0, 1, - mp.Near2FarRegion(center=mp.Vector3(0,+0.5*sxy), size=mp.Vector3(sxy,0), weight=+1), - mp.Near2FarRegion(center=mp.Vector3(0,-0.5*sxy), size=mp.Vector3(sxy,0), weight=-1), - mp.Near2FarRegion(center=mp.Vector3(+0.5*sxy,0), size=mp.Vector3(0,sxy), weight=+1), - mp.Near2FarRegion(center=mp.Vector3(-0.5*sxy,0), size=mp.Vector3(0,sxy), weight=-1)) + mp.Near2FarRegion(center=mp.Vector3(0,+0.5*sxy), + size=mp.Vector3(sxy,0)), + mp.Near2FarRegion(center=mp.Vector3(0,-0.5*sxy), + size=mp.Vector3(sxy,0), + weight=-1), + mp.Near2FarRegion(center=mp.Vector3(+0.5*sxy,0), + size=mp.Vector3(0,sxy)), + mp.Near2FarRegion(center=mp.Vector3(-0.5*sxy,0), + size=mp.Vector3(0,sxy), + weight=-1)) flux_box = sim.add_flux(fcen, 0, 1, - mp.FluxRegion(center=mp.Vector3(0,+0.5*sxy), size=mp.Vector3(sxy,0), weight=+1), - mp.FluxRegion(center=mp.Vector3(0,-0.5*sxy), size=mp.Vector3(sxy,0), weight=-1), - mp.FluxRegion(center=mp.Vector3(+0.5*sxy,0), size=mp.Vector3(0,sxy), weight=+1), - mp.FluxRegion(center=mp.Vector3(-0.5*sxy,0), size=mp.Vector3(0,sxy), weight=-1)) + mp.FluxRegion(center=mp.Vector3(0,+0.5*sxy), + size=mp.Vector3(sxy,0)), + mp.FluxRegion(center=mp.Vector3(0,-0.5*sxy), + size=mp.Vector3(sxy,0), + weight=-1), + mp.FluxRegion(center=mp.Vector3(+0.5*sxy,0), + size=mp.Vector3(0,sxy)), + mp.FluxRegion(center=mp.Vector3(-0.5*sxy,0), + size=mp.Vector3(0,sxy), + weight=-1)) -sim.run(until_after_sources=mp.stop_when_fields_decayed(50, src_cmpt, mp.Vector3(), 1e-8)) +sim.run(until_after_sources=mp.stop_when_dft_decayed()) ``` After the time stepping, the flux of the near fields is computed using `get_fluxes`: @@ -82,18 +95,34 @@ near_flux = mp.get_fluxes(flux_box)[0] In the first of two cases, the flux of the far fields is computed using the `flux` routine for a square box of side length 2 mm which is 2000 times larger than the source wavelength. This requires computing the outgoing flux on each of the four sides of the box separately and summing the values. The resolution of the far fields is chosen arbitrarily as 1 point/μm. This means there are 2x106 points per side length. ```py -r = 1000/fcen # half side length of far-field square box OR radius of far-field circle -res_ff = 1 # resolution of far fields (points/μm) -far_flux_box = (nearfield_box.flux(mp.Y, mp.Volume(center=mp.Vector3(y=r), size=mp.Vector3(2*r)), res_ff)[0] - - nearfield_box.flux(mp.Y, mp.Volume(center=mp.Vector3(y=-r), size=mp.Vector3(2*r)), res_ff)[0] - + nearfield_box.flux(mp.X, mp.Volume(center=mp.Vector3(r), size=mp.Vector3(y=2*r)), res_ff)[0] - - nearfield_box.flux(mp.X, mp.Volume(center=mp.Vector3(-r), size=mp.Vector3(y=2*r)), res_ff)[0]) +# half side length of far-field square box OR radius of far-field circle +r = 1000/fcen + +# resolution of far fields (points/μm) +res_ff = 1 + +far_flux_box = (nearfield_box.flux(mp.Y, + mp.Volume(center=mp.Vector3(y=r), + size=mp.Vector3(2*r)), + res_ff)[0] - + nearfield_box.flux(mp.Y, + mp.Volume(center=mp.Vector3(y=-r), + size=mp.Vector3(2*r)), + res_ff)[0] + + nearfield_box.flux(mp.X, + mp.Volume(center=mp.Vector3(r), + size=mp.Vector3(y=2*r)), + res_ff)[0] - + nearfield_box.flux(mp.X, + mp.Volume(center=mp.Vector3(-r), + size=mp.Vector3(y=2*r)), + res_ff)[0]) ``` For the second of two cases, we use the `get_farfield` routine to compute the far fields by looping over a set of 100 equally-spaced points along the circumference of a circle with radius of 1 mm. The six far field components ($E_x$, $E_y$, $E_z$, $H_x$, $H_y$, $H_z$) are stored as separate arrays of complex numbers. From the far fields at each point $\mathbf{r}$, we compute the outgoing or radial flux: $\sqrt{P_x^2+P_y^2}$, where $P_x$ and $P_y$ are the components of the Poynting vector $\mathbf{P}(\mathbf{r})=(P_x,P_y,P_z)=\mathrm{Re}\, \mathbf{E}(\mathbf{r})^*\times\mathbf{H}(\mathbf{r})$. Note that $P_z$ is always 0 since this is a 2d simulation. The total flux is computed and the three flux values are displayed. ```py -npts = 100 # number of points in [0,2*pi) range of angles +npts = 100 # number of points in [0,2*pi) range of angles angles = 2*math.pi/npts*np.arange(npts) E = np.zeros((npts,3),dtype=np.complex128) @@ -109,9 +138,18 @@ Px = np.real(E[:,1]*H[:,2]-E[:,2]*H[:,1]) Py = np.real(E[:,2]*H[:,0]-E[:,0]*H[:,2]) Pr = np.sqrt(np.square(Px)+np.square(Py)) +# integrate the radial flux over the circle circumference far_flux_circle = np.sum(Pr)*2*np.pi*r/len(Pr) print("flux:, {:.6f}, {:.6f}, {:.6f}".format(near_flux,far_flux_box,far_flux_circle)) + +ax = plt.subplot(111, projection='polar') +ax.plot(angles,Pr/max(Pr),'b-') +ax.set_rmax(1) +ax.set_rticks([0,0.5,1]) +ax.grid(True) +ax.set_rlabel_position(22) +plt.show() ``` By [Poynting's theorem](https://en.wikipedia.org/wiki/Poynting%27s_theorem), the total outgoing flux obtained by integrating around a *closed* surface should be the same whether it is calculated from the near or far fields (unless there are sources or absorbers in between). The flux of the near fields for the $J_z$ source is 2.456196 and that for the far fields is 2.458030 (box) and 2.457249 (circle). The ratio of near- to far-field (circle) flux is 0.999571. Similarly, for the $J_x$ source, the values are 1.227786 (near-field), 1.227651 (far-field box), and 1.227260 (far-field circle). The ratio of near- to far-field (circle) flux is 1.000429. The slight differences in the flux values are due to discretization effects and will decrease as the resolution is increased. @@ -132,6 +170,193 @@ plt.show() ![](../images/Source_radiation_pattern.png) +### Antenna above a Perfect Electric Conductor Ground Plane + +As a second example, we compute the radiation pattern of an antenna positioned a given height $h$ above a perfect-electric conductor (PEC) ground plane. Depending on the wavelength and height of the antenna, self-interference effects due to reflections from the ground plane will produce well-defined lobes in the radiation pattern. The challenge in setting up this calculation is that because the ground plane is infinitely extended, it is not possible to enclose the antenna by a near-field surface. A non-closed near-field surface unfortunately gives rise to truncation errors which is described in more detail in the [section below](#truncation-errors-from-a-non-closed-near-field-surface). + +A workaround is to transform this problem into radiation in free space by making use of the fact that the effect of the ground plane can be exactly reproduced by two antennas of *opposite* phase separated by a distance of $2h$. This is known as the method of images. Additionally, the odd-mirror symmetry plane can be used to divide the cell in half in order to reduce the computional cost. + +We can validate the radiation pattern computed by Meep using analytic theory. The radiation pattern of a two-element antenna array is equivalent to the radiation pattern of a single antenna multiplied by its "array factor" (AF) as derived in Section 6.2 "Two-Element Array" of [Antenna Theory: Analysis and Design, Fourth Edition (2016)](https://www.amazon.com/Antenna-Theory-Analysis-Constantine-Balanis/dp/1118642066) by C.A. Balanis. In this example, we consider an $E_z$-polarized antenna at a vacuum wavelength ($\lambda$) of 0.65 μm embedded within a medium with $n$ of 1.2 and positioned 1.25 μm above the ground plane. The outgoing (radial) flux is computed along the circumference of a circle with radius 1000$\lambda$ (or 650 μm) centered at the midpoint between the two antennas. The angular range is [0,90] degrees with 0° being the direction normal to the ground plane. A schematic showing the simulation layout and a plot of the radiation pattern computed by Meep and analytic theory are shown in the figure below. There is good agreement between the two results. + +The simulation script is in [examples/antenna_pec_ground_plane.py](https://github.com/NanoComp/meep/blob/master/python/examples/antenna_pec_ground_plane.py). + +
+![](../images/antenna_pec_ground_plane.png) +
+ +```py +resolution = 200 # pixels/um +n = 1.2 # refractive index of surrounding medium +h = 1.25 # height of antenna (point dipole source) above ground plane +wvl = 0.65 # vacuum wavelength +r = 1000*wvl # radius of far-field circle +npts = 50 # number of points in [0,pi/2) range of angles + +angles = 0.5*math.pi/npts*np.arange(npts) + + +def radial_flux(sim,nearfield_box,r): + E = np.zeros((npts,3),dtype=np.complex128) + H = np.zeros((npts,3),dtype=np.complex128) + + for n in range(npts): + ff = sim.get_farfield(nearfield_box, + mp.Vector3(r*math.sin(angles[n]), + r*math.cos(angles[n]))) + E[n,:] = [np.conj(ff[j]) for j in range(3)] + H[n,:] = [ff[j+3] for j in range(3)] + + Px = np.real(E[:,1]*H[:,2]-E[:,2]*H[:,1]) # Ey*Hz-Ez*Hy + Py = np.real(E[:,2]*H[:,0]-E[:,0]*H[:,2]) # Ez*Hx-Ex*Hz + Pr = np.sqrt(np.square(Px)+np.square(Py)) + + return Pr + + +def free_space_radiation(src_cmpt): + sxy = 4 + dpml = 1 + cell_size = mp.Vector3(sxy+2*dpml,sxy+2*dpml) + pml_layers = [mp.PML(dpml)] + + fcen = 1/wvl + sources = [mp.Source(src=mp.GaussianSource(fcen,fwidth=0.2*fcen), + center=mp.Vector3(), + component=src_cmpt)] + + if src_cmpt == mp.Hz: + symmetries = [mp.Mirror(mp.X,phase=-1), + mp.Mirror(mp.Y,phase=-1)] + elif src_cmpt == mp.Ez: + symmetries = [mp.Mirror(mp.X,phase=+1), + mp.Mirror(mp.Y,phase=+1)] + else: + symmetries = [] + + sim = mp.Simulation(cell_size=cell_size, + resolution=resolution, + sources=sources, + symmetries=symmetries, + boundary_layers=pml_layers, + default_material=mp.Medium(index=n)) + + nearfield_box = sim.add_near2far(fcen, + 0, + 1, + mp.Near2FarRegion(center=mp.Vector3(0,+0.5*sxy), + size=mp.Vector3(sxy,0)), + mp.Near2FarRegion(center=mp.Vector3(0,-0.5*sxy), + size=mp.Vector3(sxy,0), + weight=-1), + mp.Near2FarRegion(center=mp.Vector3(+0.5*sxy,0), + size=mp.Vector3(0,sxy)), + mp.Near2FarRegion(center=mp.Vector3(-0.5*sxy,0), + size=mp.Vector3(0,sxy), + weight=-1)) + + sim.run(until_after_sources=mp.stop_when_dft_decayed()) + + Pr = radial_flux(sim,nearfield_box,r) + + return Pr + + +def pec_ground_plane_radiation(src_cmpt=mp.Hz): + L = 8.0 # length of non-PML region + dpml = 1.0 # thickness of PML + sxy = dpml+L+dpml + cell_size = mp.Vector3(sxy,sxy,0) + boundary_layers = [mp.PML(dpml)] + + fcen = 1/wvl + + # The near-to-far field transformation feature only supports + # homogeneous media which means it cannot explicitly take into + # account the ground plane. As a workaround, we use two antennas + # of opposite sign surrounded by a single near2far box which + # encloses both antennas. We then use an odd mirror symmetry to + # divide the computational cell in half which is effectively + # equivalent to a PEC boundary condition on one side. + # Note: This setup means that the radiation pattern can only + # be measured in the top half above the dipole. + sources = [mp.Source(src=mp.GaussianSource(fcen,fwidth=0.2*fcen), + component=src_cmpt, + center=mp.Vector3(0,+h)), + mp.Source(src=mp.GaussianSource(fcen,fwidth=0.2*fcen), + component=src_cmpt, + center=mp.Vector3(0,-h), + amplitude=-1 if src_cmpt==mp.Ez else +1)] + + symmetries = [mp.Mirror(direction=mp.X, + phase=+1 if src_cmpt==mp.Ez else -1), + mp.Mirror(direction=mp.Y, + phase=-1 if src_cmpt==mp.Ez else +1)] + + sim = mp.Simulation(resolution=resolution, + cell_size=cell_size, + boundary_layers=boundary_layers, + sources=sources, + symmetries=symmetries, + default_material=mp.Medium(index=n)) + + nearfield_box = sim.add_near2far(fcen, + 0, + 1, + mp.Near2FarRegion(center=mp.Vector3(0,2*h), + size=mp.Vector3(2*h,0), + weight=+1), + mp.Near2FarRegion(center=mp.Vector3(0,-2*h), + size=mp.Vector3(2*h,0), + weight=-1), + mp.Near2FarRegion(center=mp.Vector3(h,0), + size=mp.Vector3(0,4*h), + weight=+1), + mp.Near2FarRegion(center=mp.Vector3(-h,0), + size=mp.Vector3(0,4*h), + weight=-1)) + + sim.plot2D() + plt.savefig('antenna_pec_ground_plane.png',bbox_inches='tight') + + sim.run(until_after_sources=mp.stop_when_dft_decayed()) + + Pr = radial_flux(sim,nearfield_box,r) + + return Pr + + +if __name__ == '__main__': + src_cmpt = mp.Ez # TM/P: Hz or TE/S: Ez + Pr_fsp = free_space_radiation(src_cmpt) + Pr_pec = pec_ground_plane_radiation(src_cmpt) + + # The radiation pattern of a two-element antenna + # array is equivalent to the radiation pattern of + # a single antenna multiplied by its array factor + # as derived in Section 6.2 "Two-Element Array" of + # Antenna Theory: Analysis and Design, Fourth Edition + # (2016) by C.A. Balanis. + k = 2*np.pi/(wvl/n) # wavevector in free space + Pr_theory = np.zeros(npts,) + for i,ang in enumerate(angles): + Pr_theory[i] = Pr_fsp[i] * 2*np.sin(k*h*np.cos(ang)) + + Pr_pec_norm = Pr_pec/np.max(Pr_pec) + Pr_theory_norm = (Pr_theory/max(Pr_theory))**2 + + plt.figure() + plt.plot(np.degrees(angles),Pr_pec_norm,'b-',label='Meep') + plt.plot(np.degrees(angles),Pr_theory_norm,'r-',label='theory') + plt.xlabel('angle (degrees)') + plt.ylabel('radial flux (normalized by maximum flux)') + plt.title('antenna with {}$_z$ polarization above PEC ground plane'.format('E' if src_cmpt==mp.Ez else r'H')) + plt.axis([0,90,0,1.0]) + plt.legend() + plt.savefig('radiation_pattern.png',bbox_inches='tight') + + print("norm:, {:.6f}".format(np.linalg.norm(Pr_pec_norm-Pr_theory_norm))) +``` + Focusing Properties of a Metasurface Lens ----------------------------------------- diff --git a/doc/docs/images/antenna_pec_ground_plane.png b/doc/docs/images/antenna_pec_ground_plane.png new file mode 100644 index 0000000000000000000000000000000000000000..9a074210a51bbb75f8854d98a8e63640c570d9a1 GIT binary patch literal 85864 zcma&ObyyY7+BHn40+NcPfJjMq3eu%Wx6<9+B}g|SB_-Wmdy~@L-QC^r4d-{x`QGQf zoKsAl`UTd+?`Sn~ zMRDi6f1{|t8oX=!(TX^|QjdX)hkKp(P8dCijLaYcj-kRWB1>}MFk&iRSbXG<>}cxc z?)t9w2(=4j@H&-pkaLr7^M!)ckBoQ0|M`)VUEPAg75)65pFBRLCA$B{&Hev) z5mC{neJc5Z={)hYeOh&xOhHgcM>kY~q+V+cQeTWmc84b2aKe+2bv^B*B0A(?G9FKMWxyvevpG-a#MuQ`TYOD=SmXiAx^4aUf`Ij1M7h5{vwhqvEg^Y32+Qb!2TF1k1$L)RYd->pyP( zdz*Fv5uDl=b54{i&5xIFN19!&qa3c6lP|kP8;d?AeF)=ayu_p1}PDCn{ z8}#D8mH8>O`Zw(ORInxUjzvoKGbdR&KO(PD*t;Zh10~ zwz1JSRakJD!$E0jq&RP7bo+iXb6h^Qw||@{RBNku*zM}=rP~X6|NcFj=~z(SmmJ&E zeoo$%Na81}ODi=^?xOvBM^`=xqpYl~T&*YQBg4GSO4udHwzd+}(o zys?4Q+!}yxGF!dx;1v-RlsmM`6B0c$yHKK|evoeqz1T26>@~Zs(k|H?N*8Iom@x}| z%^5D>af9{Z#aD;N!QNiIgSk3-wQ~Q@nPN7J9+$(FCSOiYPk)4mZ`>Y2jppke9Lk%W zsv(~V{^NB?>uYP)TSMdnDZJuhVn~*jmSE?T!H~GG9k_v8A!Cy0kL7;eTWCu9k|UQs zZfY|6=Q+RI#Yd^`g(kP@Iy-7%6y+lI04P)t22=2kX<=c(+d#2+>Dsj^)!Q4U-swNDMDKi>O#hx_+QwgA+6h_I&$mrqQ7(pR7o-8IN=CLm|bu+`O zJodvB=qlD~;Bvd52RmZFHRJ=-*47?Q)SBgHH8p<)3JBOnso~1(CW$n z29G9|ePto3?nCIK_BK(ffXA=g+;`tGh+XGnA4hZKabCUZZn|6ufkL55hu7trvn34< zyJE`9_%Ux~zxBp5RGLqhx9>~wT%>tDB!aLzT8oh{HyzLa<^|pUljM9hEIwUjrc%e8 zot^yx4^PzHoe$XcY;QWIu#o;@f41`{vmROvT>(`1+JYflzcZY;y|eT5(Ce{5^%-J` zR;i%It%9p7PgGP?M|jIjZ@&4pOl^D<#I9Ir+EbZA@}ETY8ia41UMI$MiH;!HN2BR# z3ytXvQS|A02eZ0w9l_sbWfNIM;cTbN4Q!8=TFO0cFIc#^R2Qtw>Z^ooYy zcQ-c+p>`b|SwDU3X$Y6?5h|MOSh38{AhZ=759ZXWO-9A4O~<7;%qC>QiMSPjwPtoa zrm+(kI@Nvwr;-!`b}c_T=dhf62m1;O>l1xyP!P&A)XNKu0}Kp7Sevde>NQUbAzfE!^*-^9Kz1QQGLX$al4!$8nV{x18)F~ zy1vxnS7K&GlN}lo62qWT9SfZE{auMjAO?0MV$Q(CK~3Qtc)D=P)4~MZ?AFz!u8iYB zMcV}!ZF?l!v3q%_itfKA6gCB+0yW0ny%lbH1zNM2}eFu@5cUmQGAeJn10NiGBK{T7_Y`-R8iF4>C!l zUT1h5Vc4I()tU>|7VSd^v+x|2`@*+hDE=u+Q+?(fqrfL_F7~BAeZm6MC{(WsmW+98 z)5}nU8y@cB><^p!}B-b!+~UO^O?#Y$Ry6*;ET$fkH5t;>d5&a zJ%>Sg_Kcp0KZ(bIR_|}<*Q=xDu>zF{kV2T;F3i~opQm|TB#z(G>h4!hkQhn6dGiJZ z6O)>jHaI8M70nw&6(Of(UjRA*m(u}J|1Wk5Ztg@dKJ(XBgx^=^Il@6KvpLPb*v)$Q zH%26Au9y5Uji*Y#F27L|MzQB1{_;nL=JGn5#&~tTH{tYbRDQI{%?T8*zo5b;vYB9m z2zkmap7*ZW9_LD6MQypCGlz`X3N>oNfw5l@682mjuS(Ac7TsHeFXuZS`*OB53?I{t zpy}0QB_V;bJ6Xa=)H1nk|4~%*X-?mtzcxJg?Cnh{C@?F#m!c`MMAx`+HJB-C2E~Uq zrOme&8?5kZuVU~ezpMT7?(VrOaQm)#r$t#%m8KhADnPzCF|L|vee?o>1i9XL4P#lm z{JpiaclQy=&*v#uwLRxlbmm8+q1v4&S_PjpxVt(IeaQ^x*U~&wWd`DK*P-HV&rZq2 z#S1GdtGm0q;*j;3-Swhn=m8=Zy)8^AhYcB=`cAl8r!8&(eJ2!h4x_ zKlq_`XyKhRhxj?GrD^#8f-QMU*x1-vayc=Fji=$Ug5*)A z*V(htpF|)qQDG#1eRn$83+l!7aVM!XP4--+Nelv-`0EnlCfXtoS~ns@3IlKR+3KP_ zu)?y(o3rgN8^>`@dx&NIKbbS97SY6tIjt7xW#7h_PZp;&y#vFkPU+_>^j0j#oqrE;W8vLOk|CG>7!8&Cguz zgZ-LJX4d;|@8pz#ii#Q#aSx`49jW7S9yfk?J)${ZLM{7?a?yG9`SnggNe?KoIy?3} z-1=Qui76=-4v$dx>vDuO5lnu4yCi(3M458gB#x)l)Il=X(-ZxiknJ7Ejh3=kRdo@V zIT3J(vcc2>9Sszlc}UN$G~%r#DA;8WajB{AMTCV530rFZ2uiA*80kvVo~C>OsXQj{ z#Xp#ocI{}njfl@V5|q>Oii%-lw%Yo7Y#f{~=Dg$xm-9|K%h2rDN~=W@zZM}=Q`(1z zhnHbuFwc-g$~Fy+j7~SxyjZN4gcdw+Eo9!}2%}`hCiA=D(@+f$4+l_WuJ7;e?0Oc> zPt2^+OF}*Gua4R<>#UdI0Ki%W84`q2AV>h%pyW|R@CobdQ$ipRP>2;;eKWPH-c0iyd4yl^{wGdnPjfADThX$lyJ9$xvww=$`tqZw3FQ{$)-H8{1D zZkVPB1a=idX$g8kp<1d7D|mMVAHjd|QWyo4bXIo{kLyY3gQ%QbIEb^Mp&^zCOkGfq zon2ishK-NT&kau2y7@ru2T$Pleo(uI>aN}GOv6<7^z^KNOu+YeciKU6d2;d%R79$9 z+=MY5i+u_z8k5g_W;Y5g5a14qdll*0O|H)f*@74$R~dKTf8RaWcM?0r-e|gcY$6~a zsNT)94WaZ=#+$M#Dp!*?XzSj&I{NGQfbmXMearOhAx;wkSRmulJs2KrD=KxYlMBZNGs}MMnw- z3k%B|%Xe*Utu}v~_5wE~}35 z_h#|4&vRm9W3g*$E}i6rgoFYh8p#3wW@2SOVxynDg-)fo6cnQw08N}%=0G+mkfZN6 zwEGdE!&|Rt&A+bYG~WSS7+rj{cmdLwQB>&>S5q`?UVLWrJunal6aZjPRCM%A5Vlvh zx1#`+{EpwD_~|NY0%3IACTFX9i>oiGWzztX010C9499yh$g2+ z52wV;02ok>J04Qv;sRo^NlDXMcP&czTkwS=Q&T}k9lLE;$s*mcpGdp0oGSGJXouD1 zM4!ZMuS{ycX6a{-!Vw{!NeJA;TGN~3S>8Yj@$j|tNuAA}IJ)-sb}Ryd&XtZ3*xSZU z^y-R>z=HA{XkZ{RF|Q*f56`c{!a_7W4@8UDs3;q)(8=oA@#6iG>a!P|oHe_KcPQjt zJw4?+c55>b#R&+yXLG5t$$egBby4skk=uF2FNuFs)hPh?ec+K_3VQNgF1T4OuZl;I zP_eRBw8wOw$TdqPJ?w05ii0=;MB_aNe|_O(jlo)eqlE?kfEn<^(Hu;xbpa6xe;T)2@QAM&b!C^`0Fc8V=J78mpaXtOO-}CfaDSViwj@n+ z4Oo*g$cD>$8a0-Pzs)9#uWoLz@$tn#{!r*?<%oNn<6&ZADjjQ75fyB_QB89@;6A9| zeZSzm8U}2bH5Z4Ql$Ms(Z}B;*ah4F;WcSWr7a)41Kq0lYv#YaRm-Y*!v!NS35OXjxQnk*qL zQm>-DJO_{#XQswV{&b_i&iVMw>E>V#7#5^F6mkT4fosYN!~Smo0Y4+*dr6KkTWzs= zx#+c-ouDn8Ga5HFp)`yMtDvBOrXrsPFd?X`9b%WlA|e(uB~^8!#%y>1GAU-w??ts0 zH~<0%!tWINcpp()%VpWHU)?%9yW=^iG5SdAdG+-PIu)u_SUWl8I2|s4+^WlxSPLcu zeSF{rxS3wFwzS>Dn2iub5;K4rojc6Tf8zw@vvY4cFvf7{SCNs?QLws}{{Et=^Cv*k9>WN9gxGRx+dBp5BLg^fcsB8I_0BYMkvU_LY|%iCMG6N&J@FBc41(q31G6C#W+Yr z%`E&iV4wgmfI>;1QaS*HQ$^{;VKtQ(YUTPrWIHvZeP0Z4f*`1`!t%!g6*dYM9tl^# z5yTk)?2@1ypj+Lmq>}KvGTCj&z`?_FyPQyhOx2gdTXUqoaJ<@Sx6}-~F_6;xH|+Hb zVJu?eCuW|==VF_;eKB*7<5VFr>q1-wncsxc_N^3Vq_jOGig1{=HUD zrOBxC{rRNHa0Vi<3Sg=L%t*@0GT7)p?o9q-`U>ZEvG)}yJx^6kUS2*rI=c3JLIdDu zyRv=h-jXVhk0>p_Kls(&U(CAfS4~cp8=wPe15~h~8Y>;oyW>vVOC^OzB2G)92B$+q zP^g{;a&mG4K=&n=HQD2(*Q1J|hE7r8pucYb&HlYM<2F0p?4T*_J_v*jE*_MBap>eg zEMI`pUSMPUw&)5KjE{i9wcYmFSy)-Ohcm^OgX{t2Pfbmo^SGP`fD9iZW@-5z22=!2 z5)zWD>+9isCAvOCR&H)?m}jq85Wqqz)fs>eLQYTr%&*0J*qD-%(jUkytTrp{t=n-E z2fZ^E{QUey0t4ls7TJL+`Gkbc&y7h*NkhdbfCCGH&DKjijvo_nT5zE@teD=>doKyT zRH5hFr7!db3U+!3XhJYg9B6O4Vtb~F4!|kK%UZ9;dnX{OOf|Z&5{7+WThj+L#ra~| z$OT9uXf>y2XZir~TwPs7CMAVLL}0cBVj6AqC3fJS)nEMF8^)A&od?ncfS#aKQV0q{ zRo#rM)E|H-H#^2CwL6PQk*c!UHB()hU7}O)X205cS-8*8F5Ax8;TbtOxxS&{NRb97 za4{8gC1 zaU!#en;Wb3Qgf@>>TAFjK|pf@1&CTcbqypP+PUh&2U81;U3(rtX+z|4L`o({ferr1 zr^yv47g^ict){vi(Aeovol`L~mVE2P!pHwB&Diwu7QDO3&;+oe+~7-B$<8Ol{RLHR z+C|_W`Bth3A0$R!MD(Dbpwj%>1O*mAbT$UlzE+R?H@A|KL58;J*C!y)~Hgf`9Z3?sAfS*RaG@{ zP*Pf24`dYJgG->gFG4(u>b)v56xqYX+Qdmc^iNNpwqUAE58Y}w`<+7~7O(_20p{Z(`cG5fRi6skMu98drv~DJ3{cG3sB;&zP=~X6-j`xOw0tgS}jEoWZ4C?G@`Fp9sJn zCX>ZlW#j23O4eR`+0qFo05RCkTGW(*839)QmpaY86`is1Q`qpoME#Y%ojDXw5S~C! z5e>wMVN>cB(5xyp_D8B<(_?zoGp|j-R%@!&&ARb5{zA=O82oE@j#--3HIqd0JV%Yp zdbBS61z`h8QjsRx`&whIF3$BBs{tp8XSAfEiURb>fZ(F)>gr{;DA22wkf$97VW!c< zSTPN1e4c&Zzub;1hlkTQ4M?QG%kvh~1zI4JiwPCwd|G_hwy#w1vgs@&XlHfQ*@v(af1xcuRf_{AAAUuqog%Ug0U$@fo!> zYkyCVXT<{a6qCa1g#REb^&__268}n_fl!55p+H1?Jg{m6MU29j?I$}=);rVJJ|F4A zP-0%#K~U+wWWSS=eSTb*iHJ z$o^Qr?fALo!zznwOsXXRTjt9CA=^uvH`@r99;aA`{C6ZN!aPc}NJV1O-v#_GADknm zD9ZTe&rMSIPV^J0`!3%43*`(Sk1v;S;W-2^gt@U69kLNl7A$mR%-LJsd8}I*J_;n= zxSS^rTOq+GJum#Xxm3BN1^lsyf(6@`@=j=*eJE|SIt0QU-L5iV1GXhRF{&;)q?}ic{^}I(pzmY zi-ztF^d2kd{a--Ahqrf{CmY24tcQK%#2>OhmS2!`@(RML2*LmKrbEe+M|i{foDuu@ zdeh2K2vhS7ipRb69WTclw)SVP@PFMMZr_U9ps6z$SD^?I_M|Zvykl2txx56FT**i0 z6~j)|Z|P424UmnCsr|yars(8GqKyTX1Yk(Db3V>(q_-$G=;=Ogeo`I3Ik(m7t!PLO zAAfFp{9(;p43%oq7Pa6ji&Ck9NTt2?P_^kqgX7Qlipu>$ljH0$yW5`ASz+GAVrk)N zR@M3Y1C4QILSY%n;Ss^La%wcRX=1`{nZZ5)s?nuAXG=F$(3r!$aZY&h6 zPc`D;7kT`1ug0yPEfSoN`9nOh)CG=!<$dW&F&+lZTcxK^#I^b3{<2>zQkQAQOP}&R zf4B)$ZZ)Jyhw0)^nLAVE-3keP+PwGZoVZHCI9x2Rg}|FP8B8(fT~cz62wCn!w0{kya#|fUu731KHdH`)%Y4US-&Ai~*QQG-$QSuG07tJL#wqGm zg4oG-i91a3WnvuJ5P0#Ut5aFqM}NU>ACocGGgW?kQcPr$N<0?y;U8(z4zM17cYN1AD8bOC?U8`%&lb8 z=DFj3zJ8Z+^7ZrZ%0eQ*e?Y5RX1{W6B5Bf&5X)@o=m-F^QB*>LI8Yz3gsl&oE?FFQ z6fsEnBpMv|pR{5f_hUo~vCvZ2G(>8ofs<8n(e(o!@9PvNoBIQ=wKuhUGkBNUDH2=O ztaCg;@7sip)qCtbeqAlIn!IDe_1MEx;1nar6kWEtVS=x|muofZoSLo2tLfYOk`kCT zCieNW^~SR~7i3d)38hH=#s)Nbvd0K05pigSVsI0*1_X{|el250Fadg8#G8Lg!j7;F z<`a_wRSykX33MqD$Nd@6%Y%8BB_CvGumCQv2R=Z1#Zg*7Emy6vBxY}y74a-I+M*Z0f=_y2i7^W`;WWH_Any{3kd#F!es9Vau9@}x1d!aNSPzHKDqhX87oc-asmdDWhWw`&U`|JxU;($pz$#|pH(t|KOs&xd zj*~J&b^Xq&u*f%g%CFjSM7KK>47VY z?`J;`$u~s@3KXBk9iK;)7&IrroDAR{!1^VJ-k`>BBiS*BI zCv%hH-J8=&nyVMOTi^RdCq(LThQ=A%bqIK=JeH}$v9PmOjWCaM0FeMY640%1jE>?y zm6hz{@oN@>qCWUK27UiK^9g2?LSK)Lk{L4AT1Rr|rZHsb{k-nM&9m`rOBAl%9Ccvh7^nG;gQrY4IGhX$EOGo}^OtDCRPf z)esJD>uNk?&-GCPZ%;IjT|r^#ba1)u2a^#-LUbkl=I4dyZfR*ZP3S_O44BFVzZmx5bIfyoQzBXn83fnEj6Zdp**k*#8|IiZ&&RiVs$^FVMBcYtD_rM|@-M z|E^y2;EFvIm|niF)W_c*b~7n^bdr<3#=N!C6i&TBUHSH;891$p^|#R^)3cdbaKg|b1=ou6Q^cx4_QwLpg$LB z`8{b9S#6(iD>3aEq^qW-)iG%>J4S;uxuH zB%HXD9Pt4X_tEmaT)#TTRk7^vg`6KsM#Y(?vF@`9y@q6c_BUK;trVTau zfwJy0>~A1ns|vLF0&^u_5GC6%Dmn{K2fozj_PTbEx-!{=aaZ8`tW}famk*Ao7-Szv zlo26X5|S$?=Ud*;dAE_1w^I-UY&Pnxo}X;|IL*ol=1)6EPUuolq6hm zA6=t*Kd3%1R^xkYzmyn!SkBpH>OzsiEqr6g%3V9TRI3|HC=~hH0}U&A>-gQN%7oF4 z-O`5g$wd8YUYI4Phfn7Ls!56cT@Jf2Tr=xmcW#9;Ez{SQeH*xuMfMDkk#on;UcCwr z|2?AUql5In+JzPV^tDyGiv>pB*y`@vQQejTKF&JYiSC-PKOdMjY6zlNmD9X7-CG}i zkVZ$YY~|txc5`ASzw#Su_NIQbH3kW_2p}tk8u)ql*+nL(Fpy6e-iT16%JNCzFR-OC zA$TLnYI4it2t}5Q%Z?^sKU_iCs*CvB4(@gB?S%#?sgWVtn5P>p>Bi#XUug2183Sk! zLULC+{+k5QmFDR1qEo}K&ufPI(xh1+?!(SJ#iu%kd+)@Nm9rN3YksG31-LI=2^+8$*M%gXl5DWe2!5lFFk)=I#Cr^v~t=~0&wz8i5c_P$ST+CD$T zg0WZcHn_Boj2?rI3A;&jKQKS8_pLJ8UQJ_OSsdFuT%nJJ5%$`wq1d*-y*x!}yyxgX z^jO&nq7}uvqWaX~@j|Il6=0r!5J7sdTek4X2os|-eE;sLWP8LTd$P}Nqe-a8)Uc0M z$-^#VwA1Olf3!?j1LM)=UrO=7EJaQl$$1w9?}|6c8%4coUq`a?mTHYLv7^0IM$hOv z%s<{18QlAgHj%XSj-QkwjKDJ>dM+?4ElF4CE4IGo`^y=6zlu7N=9RjIN?N+!w7NG1 zzw;*3Z0o%1kfV8R^Tp|A<{&eS@08$s9-eZk&xjA~iZ(hQ@fh*{Rrvv2Q_Wq`&Wnu2 zU2D8HUU2n8xVz46p{woph{_>xu-DBVs#|(^XwXNjSu%9A-V-F{;(3!@FDdbZ2T3T| ziFZz`$17MFJprDcZaZgR0exRd>_A5xRhD0h=iHcm`=a3CO_$X-HAx*iIoaVsiIFc6 znpnS^@(3^X!eESGeHeo;sn^*y_Ekf8pIu z#XmhftQ1UpRI;+QqD@zs?_4J(`%e2`ybl<@^ixNZ0(p0Lm&@r3^u=W~pF-5sAG66c zp>BP{K5_lo76>k1jNq(y^YD^+3Z1M!N}Wfqk@9>;U?Eg<8Wj6M#@JdO4cVBA%70$M z5o2vIoDjc#y>P#6<0MojxT~&)=6*=$;EtdpJn}=IO$cHwQmiSv5c|s5ZLuBxu8;MW zl=@aM=Gtve-P7}yYu52Yarf{CULj9`lR#Ofb;S0)Y0VyM13dYo{bnVi!$&rlRPF(O zX=%KxM{9c<%*eR3?BE2iG5-}&ycj^v|GOXUAJ^vUf-V=B@V|B&oeyO4EMq6ny@Hx^M$D?j*mOLXUwI!!87dZv>4?iTWW0{ zuGQ9RLh*6RL4ko|-F5U~^a+hofsq(Se8c0|e4lb%Y8#h51kEF$xc-6aB`9}L*}doG z%8*3xS2tfe^O~8t%L)I@Up_cNOGCP*tE_GJj5MwOEOv{!Q%^=1_Y-VlB4euV{{dkt zVikJQPnQpDf`2vvp-mvw^~G*!FUpc~E2^Bw1yj8Taa@Ym#NDAI4=d z;j+7Z?_*%QHRW;;(bcfftK&tK>)k{hVr-HB0-lnS^pnq7#p`;H>-W*zT}=d+_-=e0 z49Wtv4b ziX=ddDnV#uT)ZmD^efluBgV->xb}iv_RhJBi)Sh(-MJ_JIgU|4xo+DHEOZT?reD7( zDVAWB$P}YCkoB;d&^M%EtvQS_jHJ2h=7(l!UtVT5jAWr^jTvWgGt4vFOu!gcsEI); zC8Z*%-Rm`>AM7jpl2}A~l3XQeA`K(cSTwZ-5>)P6lzA)I?yq8EFX!o~y6CRDB04f{ zcc2gP1<-dhv^TdE3ch`#u8L;%7Y`4`qll2$aK?k|*pto}L8;^X$YMJ!rQ?j?Zed!| zr*O{aC8ff<3a1C}u3tCTOpz#7S2WY zetQRfIoCdw36iz;FQjb;Yu|FsJbo~y{@~pROnPM`%3F8gC9T+Ps zx*Ia>C+qFQL86e7W#&~AL%zeUW?CWd!Tx!PXT}kXuacctdBw%E6p?AV=k(Nc58=X$ zhr8Q$ayX1(s4Iy-2(KKPrt>GQ?;bClFrY}(?|+r5ck+p-p_CiN&Z4w&lBo(*jrsY$ z6JGb|IgLkVII)d~5$tjOckl1XtSb4`T;fsDr@fr%vb8dm#poJ`nqv1gX{-AIgz9Xx zkUTFv`Enb0GTsT7obAbJxX0#ocnrpa)sa=_?a73z>#jkv zsSfZ!#ADB_MXqi)&%5xTjl;r$AI)i-scIhz4LILe=H8bylm&@8j;w|0#s+3)Urjp0 zuB0PNmF8LaM7a2j6EDY+)YnSpEAv{F#a${%00mIKS-TabF4DZX(51zv}jk z54b4D9N&l2p;Se4*VDD0e*LRo-vt34`yO$VLBELHM>>$c)0xTqoxJ-SJU?H zmTEI86!L%h&%wvT39^s%AYK$lFOHNCrS_t-`&!|^CM;Y(^KN>0T=~ARkZt*Ml!+*- z-97(3V%bwIH9!xUgr`lDdtm8b1Gt=p8%Gd#MOY=6|-N&30GLN4Gnb3cM+;(T0V=S6%TI z5{Jg+jHT@i3%Lz9o;j^wob{J+^S)*!BL3;IrOrm4zAwb~vs>$-EVJ!%esVke#!GA; z=GMP(I^N=!UdkiT3^ezowT%_hI#>k#XCAeC7D*bA*K_YD*5OF`Sa4vhO*9>SFoD;V z-@U^=Yz!!@0t@&6<71H4D@oSdcG4!kfXME9Xn$a4rxW(>K=9=ath%hE3a%2v6F~V^ z{%=l2FM^M9wZ6p&W`2k_91>{tZj(~prm@KlG*>U>q+Nv!^p!lm@Bg#drfEc42mKZ6 zEbxd6!>b^j zd)(pS%ovZUCU<(%U%-#lfyC?7+HUmq*3og;ukInlL~vE7@g@TlP*!pjLiQlGNnQ0I z*1O{ijHg_X9s2CBvn8TgF$V1trDf-WEMOlD?H$XW9dh)L)^E~>Pl>Z=uwS+Ox?70}OoT}7(tl+Xs@bxHUg^EcD_*Ql z2A(LLo85fbWxF6eK?`>m`h%>wLGqg7YGl#&fI2$mGBAQiV@ZV?(1<+Aju2X)_7(p* z`D)`Jkh*n;fHD-c^O#>-T#MQCBKM(63YYHw3@7w8^6>CoA44C8>OgZs!|@3&0PO*k z2#=eeWrPkx)25)@)59-ll!Wn%e|ybT5r0^pM4p8D;%0qUR~{LhEkL`om6TlhBZ$hP zy%LO)J=*@TE(UC(VC~Yr+n*!cUpm-4KCMU~_9J{|CbA zRwwLMsSyKe)h%CLcyv%qJl@&qFO||}0=N=wVptRzKEuu_Q|d3KNY5|sjqB!TMGWKz z8OdJgBUQoB43mcBt)Q5Z{GjChtFV+)7w2`)59i(n939G?*f>)!m+OD_vUe}vemNw< zire8Q%;n$sQ=t;g&3hrI9k@rJc0VoC)3ma%k;2d6;i$84vZi3gWafY zPbm9R&{zMaN60Tzh#i|ANs*-D{T(yQE3o*+H zj#vtuAHjxKcR$66I!1L2Es2l9g5JOM*+7V{{9sSG*twIl!C6+ART5H^L~-R(1~#g9 zG#HNb$b`fjVXm8silYF{&yG^ku+V@~Ko&>nI__t4LEh=0x%CX3ARS%ED^^1$%Q>!z zVl9o#;$FoLkEmaojf$LcnEw$^Z4N(HTlnRD(OnjPKNN{5qi5MR&d1E_-#y5~Q@fL6 zvEbkC2tO>r>Ov=2yph%sOPi1&qC3Eig*8?34H1Hc<(bJ@#s*L3kyDQWWy9|7cqi@S zIgm*l_G_omvsn6duhfkIs)H2*X|wb2N!#b*5(h-c#AJx(9L$FqnoS17-WVLCS1p6~ z43B*BFpwAVaEr6Cuy6I0zAGCfS2ueB>2_$_{%mI)osp5TAWh|yv6(;8*N#K3YFhe( zOOFp0bUdvXE!sf9e0|$}W;vY{=Tt&pQR~$1>(wJ@YquODztl~= z6exQq>7>2n0NG=U*goZRwrtFVx5uJ6c3&vh79FfD;j$^M9&jj1I_n%<4*p^9ZZb?= z*;?{tP~7%!6NQ9?BHea^obZESfN83{%cU(e80*ThI&=xyFr~n^Ia$cp0AX><%Ax^v zr1C?&!`p$00XQ8gCe8BDB_lWWGT}ckkNBQ1hsh#ezUSRs$(wkjSN6NR*)4Iu-LC;h zoKehrf2Yng2?z*aPC{MQ);6cAx*{aQmd|r1uU8HkopX0Z=<7XRxcqIjH6qa8)KGTp z>mJOrm$}|>=SZ9B8)NvgJzYzU{#b=&rE+KrWmsDFZ|l4Bc)K||czR%Q$ntyJ+cbil zhVw_9SCRhof`QBdcOng^EcxV5X$Opwf5d|o`s>n7qc4)Sr*_v@OP!6S*NCpwTivsM zi+?<6d)(SV{{)DGD;N*0TpX)3u&^G2a8&}a`EIL2A_L{&|yhn-JR}u zA$)fRiG#ejIm*9_9UGk5qN$FqHz~iQMY#Ca%o(ySJ=`?16a3Ak;P#Pn7!=;-Lk9y2*2VAR$JcVGgji^Ve6 z^#w*FyVLze;z*)KjM)JGD5oP^7rOCi3oipC=~!nB`}G!b`7yI%2o}MDXF~Hrfxbze~Ke;&`H} zrzp*IohO-%ZaBNM{Y$SAe&~jm6d^)BCVflHV7xD)JIeNdb}2NJM%F25#KEQH;{`6A zfg2(NpbP05++0EzGB>BczP_ecuM7frP11*Pp#pZ`j!P&JclpsGcmecJo$U0NjMNw` zN_Aw88+Q*Gm0C{<%TcARBw7wKL2jMr91fJB--WE19?0MY2%De6+RkqvE?Dw2ZU;&J zN`)kfkKC53lRmLHc7*kpf~23^x^HFOlT?XEi&-0LV|eL^Lllr`mP?>ZHH%AO*O93m zgU>eD|JanZG0^`+kr!OwA~Smln+jiVLsiQEJUZO^rpRhrP=-DF6z8g)SQKrjvP9E| z5rOUXl&_}dF~=X>;D(@T6RM57Nd>s0K9DCHzE3MJNt0E1a#4y#+0`B}RBjptA%`{7 z&E1$C$v%AW{z%Dt$iLXT8XaYR-SV!hhg1tu-wnx!oPEMw3Z76W4<>)Wj&s=*~I3bphtGZhy+EhM061qqA?w$LB#0e+$0D@<9 zL2ZNcB_qrv7*=GLMuhr1=rrrx zb~gu>w6FHXR+u>2y(DdXR+Hb`EB&_Rs%!P=0Nws-mtti#?M?gj`+3D;!#?VFt8BvX zo=vk#H|xJ@?5Mw^@K}eA?FXW`e*{wQaeo*x0!hEQ2R!NtVYT!U@Lz$eJm@(P zbn;qo(g>~^z*_-9Q{Cd4j-P;UQlCSK7T;|_y@yiP@yFBVr|#WP+n*Pqsw`BM3p+7> zN{dnY{kwD#LJYYhx_AuJULD|g=yJejpUMrw3|)%o2su6nT%jnABZA z>Te%c2D&43HD@j&giC1$GXz0)ju@zS|RK`dzFfW?Ml;OIzD8?4a*{|h(lU&i|}XYeh6@*W1dM=B2-q{ z*r>p26KgcrU`472qPe5yb*`eqmIrVyEKF$8(j(Lc-rEgcCabG2p&#|j!##KAD0^rW zK~k?C|HEa}0770T`UQp95NP7did|o@S|9<3e(!?6y;ho=WP0_=`pkGZ=zekdr6%9C z*4zL_$*fv5bF^jz7ScQ#MPS>OI1zCvP84>@W~y(FXNJn03eo%{?S4aU97;;Ge^#y@ z0{mvv>~Qs+WQOt!PJ3^PB|BxjtI4QH*FCi7-bBkkbo4a5lyDI)N@ZB{t%3p@`K)U^ zwdjqgqV$ui3pFBFuzhQu51yNvUJG3GI}Hd|YhGVpMPeA|PR`xX+|(n*lL~0Ej-fzA zWD;4jXD+gX-9RteEY}yCwD|bH*QcA^U0uz_Y%AN_lHgXD>@U?C6y31TOrs3EucKqg zsX9)e-Q8HEn41GFB~YQWuP5`3S6X(+yiHa{Haik5qD+1V{$E9w(*u7KQg@DH2xA=$ zk&V1X8f~?XmrvOHeIIB#47W+iOacxB3@LcEOvw?>Zyo#@$===L{tW%?aP!56H##dN zC~@3JR)MnTmp#d}{MwSf~yS(-7O%(_`pxpW_bVM^C^;;~aJy zr&e%6=Jhzxw;6%YdgWWYu46rj^^zS8Zf9aYbHBGYkdFVbgV7f6+*2Df7j99_C7Jg- zF5L8==vX4O!2k3D)O6hjVhw%M#bG&a?o1Ya=vLL7`98Z|Wd@I`pH_vNzio-9k21g#?62C=qI%w?#mvdSdg7n zM|sF)Wbz9MXwq`=?AJ46l;;k{TUCCsV{X%ZexXVUgu^tt zDS9H_!^yU3aeXx7>Gh+0@C^D6(B+#JEF&7liY7YcB{R0jC1Q-};jBYJ5em1zDt_H` z@ub$z&n?V26PjJuGCL3@dwzU`dp-V#msf&i;4RLxEK}do3lcuKBTLKc<+jP63Q8?X zG)hYeB6yb|%~acb2Yp0{5AuTd?Vu~P2Q1X&a}V}0=${82-f`gSYB;!xGIj+g$fHm8 zqb^-@*gu+h${(TTZ89_Gy0t3~#vcS>k|ngJn^wEWa@>plU)(%9>K{=EpY8j6O^%P> zz}dTJ@JSW1(4?2K;j$BE@!Y^YVJ~JQ(S^Rz%!$!F+LhQmgMyPg|L?1ZRkLQ3NPnc` z;dBmF%HVX~bUm|#HKM$x-sur`!?uXdp4X2IO9Q>(SxYW$fp zs-0qDkQKTQ5~5t9J^wk%I()@5d2R}f=l5U#=JyuMTppDdWN?~klFL~Iw=FiogBmny z{K_b(?ba^fjwJZtNE?aPiY^S7{^8x+FsiTLZv*L<0z{@)R(NvKqouIN0!663JYsVM zyj$G%KQl!X%*m;?y-0Edtku}ET&QnlTOv_x)$P6So5`z&v~94XbZHc2eemdxVEg)8 zm!H+Pr*)eO4*rOL+IXAfn) z?UxUTjeJD}uUqeE>0vZ{p{_87MJ8Qt<-cUgaE0d+?-nMOnfO{R`Zkk@@e*_}ZHBTA zaBXk$-)v=S+7F9a^>Tn`NV3{keAr*CT?wWul(U*>JPtFit05#ecDa4srB~Wm8lx2v zu9gyIC@0Z)>j>w2S3ZIU!5Xsr{2FI$HSQG)qoR16OEtnMv(TqmcEJ_`xS2r<>X4+F zZ^0{3sSi?rK1F`aCM+jV7npRwS)-8k_W!*3Bwn^vHtt(;`#!zwbvH>uJqWIbPJJV z0fxq<1|LdoKv$QFnMD4}_p>}{154i9$iJbf@iLZ6FoDOu(K97U6r$rI!$EZK+f}Z1 zPdMIleXNVZfNGe){hNQ7AaSPksnlZ_CT~I2>>KBZl+9OM!RxA6A<~**c(`qQlbr}% zWz*Ky_5=cVFE9`8Ic4o%|M&|oxT2o>#nP9tFheJLG5(T1V}08o&NQ@>lmvAb;J1rc zZ5v6*CRa?_l)z@EllruX&HUKAnR3F_K+AEUD$o6}G9yLs)-ERd=5CsdhAnH%zQOEK z-~3SvH*5E7Ef30XER6%DUapmhiDi2McJQM@N39S;OGCjH4#KS!&y&Dx+QAJh6bcrK z$AQW_A1^Dfs#*y|Trh$`0tYbRj(+4|*gW%&dkcJvT2xmF-{NK+O4xlkN3`?O?blYk zNP{Bf>?iEdpoKK$A#p#&(EVqA_G*8Va*OMdwD$~Qa&Gr~8uMo|?3@k^C)BSDBh8Ru zo3f4WMxCwAqWJmlF_f2!@kh!hCKTj9-jtiZ>-7oAVa*a39RkGv@Len#W%^vb-EHiE6d)P7YWHfpWR>@{jah=G{tcKiCZMekT;XX#{E z4Uq{is^VE}o%G4A!L@5=so-xJj29{AL#1G{`=K(viDtdU9_C5>?mw%Ztg{XIm3Vw| z;teLf-%*+wEm1#4`A$TSl=6fev>37FS#P}i`;cm-u{im9sZBHdx@O@NZWlD+`%-wI3K$Wa&>v^({8HleEgRT}M=^!7ip zA7Y+Sd^WMP@FGoCa)Wg`H=5sqy0}Mi&D9mOBJb5l=Q(elJ=Kl_8yK!>?5s#swo+~4f}hxUW-tbJi0F|E&T(D6a=HH6R^50DaD^B z!$kKM2nQQN91-ad-jSS()TcVPvj%>ObTARSeD0QpXW&QC=3s_*u^oS6{Dem-R1J|s zvxkXVBLwQdL9xcuA3Ws6!ZuZ}0c-=(6(zx<|o0bcNxMe7iF zUS!LGX*L0wYmSBSD^9JoYX`F6_%Ia4_K4+(pOx7m9XPxZH&+NQY14buzneXn&;w=} zHm_U<9Na3g5#QaTg5q3E5RYcI46m zZg4zgynw!OVo?ER(@(9pb3MPu0?n=JVPw}4Z9>bNnHy~ynSVv7hV+uRd=_5(H4>Vy zd($5mxGt-}#M~yLOo~mGlBMK;O8=B9EMrvhJ;9!GpiOl9eoWBE=d~*425fvH^g0|Y zON}*kjgfPRgGs3XrM^4bagD%phibvJ`VkzQ?*nCWSFY#*;jv{m9tLhY3ojw{dzb4J zRSlz`=?y6ZSNkDBr`{HpI`JIcA+_1X2*F|;TZ~3E<%#)DPw+%k!`*(`*juihEDGFweBt3GfcG0wN9CD8>Yd?^pn<@SiLG4 zO)I!|z?uGzHThYKXZV`;&A!K#KmT@T{4*BI6KTpA$i<1twSgA>Tk^%OWl9Xm)90)n z&mU%+DfNsSNnz5(W;V;%vbeNA!@v26^gPNSWa>i)oB)3gW?t%T< zIRwH`(SfD(O~iH%V)7M%c$qg7~M@4n|H1K=L~XP6s)=L^tz(V zpZwL)woZbpf8iM&oj#)76OMQ91z+U+qQs-tTbG*yw-vQ9ag%Qy*)~I4C~(=mixnYE z_uiBf2J?%^ZKP0AcB*Dh_xg4Q52UI42Nc~{k&5-vQnH(4_AuPj`Ckkub8AjW*wBf%>x!3{ePmy*Y~a?Z4d zM|(axR6}guA0`$0IxQ>>IqLQNo%?U#uJcg2Xq6Yhv*=e{jfq<}T~+eUmQF)h96hFiO)SC=Ta=|&b zw!Xj1HjQq3kjH=m^v@Z;Xt+FR7d=`s*<_z%0)2hzhCy~{_>0VR^Wt&VNxSE{Z6%knY{%O zK)~!e-8iu9C?cSS(HPV&kH1QI1WK<2dTDQVD-p|in1KD(#fVs{E)w%&Tt?;gew{Kr zBj8&!W|&K^Kb|Z`*zi4-ZlyQ%K}H+{!e zJD|WyOc~i|y}7FA=6@TzaL*CH&4BGw=7)KD3 zk*yq^z3y9)KArQK^B&}*`^GCavWw`-1BHB;GHclEZt0`@hWBaC4l}xbY}=f+;RNN; zzhh?p8R9a}K$b-WAJx?q{0KMy=WxL#;Y+hmpp1#oL&s>K zGK2q=aujxRF8R+pn|PT&R$~$bJW20yWH4)?Ruj)oTqx|4|L?iR&4p85jzHHRpgq1! zs!Ul*RzHpDI!siW)CE|!dY@RnC`pB0%p#mX#{%89L@a|j=8YAm8*$sqW!jhPS_WwZkf}$FI;kG0}hruQ#F=-VqIrC!IvvcN9R*r z-Ypia$#$cKDnLkr^+oW{-d<^Y`#WDrne7%vy{tFKzkV5V zRC=UrzHW0YaQiqC7(-1%;xw&nn6i(fT)Ag*Iaz~j@YC<$50o^IK}x4p$wzR49)7?qP|q*QA!fGBR4mnVZ2nQet4(j)4=0z zxzlC_Fu6{T6w_F0B)Jv6HS+jl0ViDwb#x9N==;bj?l9fH>47lWeV@mVyk@H*8kQ%z zmj3Bo2fCw%J_2uB&E*4ejIi#QStxcGMvU@uv8~UHYuV`R>>#iYQ&v*Ke*5;VudnaV zi3z{&;=nr48931N70YG}y26{Kuvlqx6ciz@j;V;b=C>+&;$z@cQKw^oH;2w8TLK#B7)AjY@LyMI&hHW7bh1(&*eRlY(XC8s~hDB;%x^5pEug?rT0 zcgE!2 z&K+_Q?SHSuYlfApd;YvA6*Ft{_%ndYNC@F0tK?qaZb`ZcA=1Q%4OtWi`c!ZQTxje-y> zs@R>`hIr(~mKm^!p4{&eJbJ7edq&tNoYE!J$IRJji-D!@jVfd%Kpn<|ibVGCqOwA> zb&`Daw_!Aw68UR3MWZfGdZOQD>k5u-MgaP$?Hl75`G1p#idk0+J7|Mxa;6t?r zt>Jj1l@P=On@Cv5=kiyU+A(&%ei+R5(b}z@9O~*!bhyk*0%40pp3OY)Ivq(hN4?0W zZp7q2TlCGSD*Y5-zW=P#yzt+3Hhz~0o!wopyE(5rgOde!cXwj|yGX9w0NBtwF`o$& zGfX6ECGlv^XXNfh_M11P4?PxsfbXB1CNBQXo5NYe^@&OIpDqUOCly_{5^m$Wyd2@c zsLqDQjy{6VKt-52NFGE36wM?H$2PRgD5ge^g4g5O9cGT=i}BOD0+Hpp5pB9Ay~kg3 z{L;_z*yPG5`R-bv+6eNSj0l36cNvmpZet-iRTV;?j)Hv_uAJ;UR!_P60-4=c9>-n|dMHBSCvUpBfv5goNP0ldI+6+nu5F7ow&t5S@%1 zjabR-+spoPA<1!aAHQ!^S7zI@sw6=uX%ngjJ5+4-n~e#AUCuqT9A?9d3bVPx$~&d_Uyx8@QL@VW=vkY8A!2U%d@Iy5*qB2(jbxC)v@lyBro59u;dwjd zrJehah;7TruQH`ge+Jn?v}htik-{9P(Pg@6hJc(`-O-`vJNKB&%|FY7#^$-yOj|zh z|Ka*Fx@m#>lwAN^tnEB^L;re~kT5PV4Rw9?9{lP8tnlH$zw|P;PXJ(~04F`f=^Yn` z5KJHON9M^Wx@>bU7MVI5_o}NllaOOYS;a{VnXMzS=*>h7F`&Xq?g5l~KAT(vv$QdR z_i^!83x5%HVqj^duHq1S0en1dw7}}YEo>Ig<}{~y*gT1Pew0Z4HGAAEtdNtZJ2C9W z4A|IM)CLEP3M{H+Sp#DHVlRJvEWK>G!hbBt(kw%cfM3BNa<;i zFHX_-I!cSF><2!9A9v#se9AoA&nJ32^ILQt168{k11~Dl5m)X(s6xPI4-aa&WinEK zSmGA+YHF4J-@40)z*`_<(ShlLPVVMxID-l-Z1N93;!JG?UJ5-MS~&7X|7IWtAZzoJ%yH;k)nbqn>b;(Y?}{U-%>?6DMOzGH6#OlX}Z+s6Fo zt;>vpe@_^Wewlmln?*die%s4lTjWAS0t)(xX3MUDgjA3P27oV8qEvkJ~a+C5)lz{D@e!--# za83$9h=)zclz!#rinL0`O^t}o$Z(lw|N1oBMT;y&_Ro8_V*>Te88J;dI$8sowEQ*B znY*mfVR-$-Zw$xg+mLbD@idn!|9*F6hO3O%B93Hsj*bx(72Kf?uzl~=YHdBEu>L~! z;PX3+{)sEI*MW;yre(&B0a19EVb2rJr?DqEP`%pehN zI1=4|<)3K(%A;4O^5eM{$*bbR%Tw4EnpQeAleumspA-=s^% zbre`;AnISsAK)+%Jcu^Ik+Wvady58XbH3UOsj8~#28_9A#)kfp(9$qcQrG^l-+X1NS$ie-?87QevhJ!x1k>=v}^B^Pl#JK^pHaA4e|Rpv$T!iB(|V ze0l-7q3-my)XGd#1CVS0W@kd%+~wrta2fAf^V5QRshPW8)FghSPyR|XougU!@Fq9B zYqLqRsFH17PMa^~wwsIWeBp^UW+#WH=XS~j8_H0zO^+b>mxtkv3dX0eN*0bYG|TTxruYh3Qp^wi6knZB#=!adDxR#EWQIa@;hOtJn~&e@Rw*tR8om| z$lu;WPq&txdNhUA6ku&**&oD{v7Gz-H1kCeH%AB{vh>u{@Xnyu5p0LTS@Eu3q7!kc zDFYl&jh`Hxwvl!10Bq!;pYpqN>+_4N-b5|5OEk*~{fhp3@R1{{Ik zijSKAVE3~CfMN+;B#p7OHI)%o=fZ*mK#8YU)5iMN!3Y~f_2fi=8Y0IRd}Z2Pje zvg?D@9^Nwc9CT?2iV7pkkii?OXuWU;khI|V0T2CAR&JC%g%v+4Iz(SdN91I&x1RQF zxB*dby4S$nd5Ow6tE0UhOx?Z{1qU{2&fgnFvyIpUhb>5ES$;Q9Y&lk@RM6sXVyJfP z`aVhx$LQfrTZ|^8LIYruHid(kloM9tU>8X$Vfz}!@;FQ}fyOnK1r@&AoS|(T-(wWb z%Lruys2rHPUHGkWY(*;ky!6B!tSeWV`!pWSew?K74(YSp&*xZ-co{#@D|Z<_aobpI zdlFRLL|E`|ePY6*51zEng{)L~cph(6o$(_?Ifj8{q3uEDNU(xUh8r$U(Hx>eTn3zNSHI;&J_ z;sgqKQB5kE1LsGRmi(tT*OMU|ANK}-OBV0X%#vgf5x&Z=SH;G%ub}hq+I0u?QaX{x z(yvJ^9g0g(X#p--SDe1?(ft&4_VSvVlFrWDyvtQCj>M`8Z*V&$lo`qYv|-5in1#$c zt5gqHR`#Fr!u7;Jsl>!g?dO%rIYZ|J-5`H%!h+HV_cmtjLn=^D)|n7=%B@`Toh!oR zDtJ(xZ+^Ltk_i~G-eK-leio%3SLZt=KoxeoQKietD@Ix`wAtEvP_70CF{$h}c!T%X zSf-lN{KQJ6PB%zKTUXKgF7$GxE!&E;^Xj=e`}oZEaTA%L=0mF%xOXeUa|zeI6Y0c= zxM<<7k07tMYCU|^%gCHJGKN5m6eY@jx4mAo&89RfI%pF0{5`Mx^l=h4nY7-iIjwn) z;Vl-gyNno+UYe&kw)k{@jXzD}DG+yycKOmvjc6d`>f8o3ni977c@%xM%_6Ij{t!xChzIBIorx*e{*DpsC8UEl^TxSh8^`K>L z!Qjz zB{+Z+H!8ojPZ~}upKoM>#ExvCM>&Z554YUcq>mL6WNxYcy6r@#{aTeqND+#_w_3dq z7btbcPr@RG&6iXx66FV1pur>Y72IT>ym?Z94Jv%(e*R9|0_v~7&k(<*#e2v8bw2g@v=n{BKOi0_9}Mu;FqVx zCT?L)Jd%}(`*Qp(i=SuwdDMrB18t?A-@}iwrW6J`|U zH-BOSGVNHw1O=bO#PXWRVES_BBvhCeK+ZDhN2J+}+9&2lpJ-qys#h|^+z`+2Q#O&pCn7ZtM#m&C}fMXX68)lfug+X9kHkp zSf=`NU~2iBmllE-R=h0Cd$EdMp_}2ue~M&pQ>yQpZ9iP&?Ep0plPe6HQuRFtic+1d zocmP6b~DewD3`OJiFv~LM&sN9sU!a{KOxoM@t6*c&hZ3VCE#Lw8Iu1aS{*Cbi~2GW zMsq35d^^O3;5w-+ynLdp8UKxrGFd5)Es`T?&!{jP`A$ONMqQdf!xp=k<-woDqC#e>FkXnN4Q#2{OIp(U<{c(f=yt#Jj840XEPB zmGkrS%-mer$M#+1u;#9-T^gs-3P<)7++7pK*x=iPzTx)saGl!oni7@6e_Z8wY% z*!h?-j$BF&6t1TDLY^SFZ2|mCzU?8QYyY?RmVf|bFx`GgCG0$J#aDU08#im~Xsi49 z5kc@n{qro+&2vt5^}}dCoUY3MnonJH^O>y1xP(5~)JqIky<4du2ti^#6g?G1%ZLq0 zNGLL_#+1uQboCq;Q$1R%YxLzX{_9#}7}Gt@d!@g?F-ODogx^~|#_gdYE*#H0>|VS^ zEZZ;*RH$;258=|&Mu2PrAm#k0E0vSAeuFe0S*tC+a~QOo0#`vY-%o)kIOhMag-jD! z*LD4>t*s5!7jmh_n%qxth3f078%?EWfed-rU?U=HzaIT?gqLmXWW`4)X(D}wPQ)UgwWw-j1f8SyI)Hb-4s;#^%%Ub!dl>sKuAN|JIuaDug3R8@~G_E4Eg(g&)aqGuv zn=S|H`1VEIPK>(MTfk?jYT3dwNZhRBg)R`NpDyZZEVNP+VOsY%OXxQAg( zWmS#zh~MoPEIVz9c9`uueHm2liwBcB`iLUshlX?tg~bT&fR!RpNbp=G$&6OlZsvTv zNg!Jp35i{w_-}*Wc$0-})!)qT2Rnm?l&AMDiSX(!E&+DejFX?_twfBiGGnsNx<1BR z&`=EzB6SUKk0+-~XpI|iDAH9EspK6yZd~wJ zNE=)PV{ZOYWsP5NK`|E|Hu8&dTf+sofhx}#_-w|<$1lEU-`v|&UixbZM@bJRCA`kw5v9sPZ{C{P35 zY*%fvP!{~!57A(*fx;z>p#QH)(;^$QG!?dze)A`3rIWcKO=QrR?m{8is3I{j{z-O& zyWcLwA^sfo?b!#ai;X27ID$9?e*e4rH=F-V`2u#g8?%P!4do>u^n`_k6bkgaR}KV) zg?kW}LkMJy9&|Z^)_(2(j)Fm%d#$gQB55<l<3$KASoP{+Fvbw=e`Wmr0xLE-i9_+Zd?vmG(!!TOMkRH3b=LiW!MHw?7tid z#K#Tif?APHk7Xv1leYzsNMr04jY!m zGBO=QwJeqceu~pRn z>XgSH(v&Zecp9(ls6!G- z-b_j3fY&ACXe{qKRsY`KO7ENB4v7bUiV_(wPJjIP@p55k{XfbXLfB0PlIBB3%Pt498Q>KNoGH-@Oy`B)L*7Q_VQw;a)F7j zl1V8eIkflgmXNB)Vib68-V!4hc|9smRHVJfI12N?MRQ5Es2YBDMV6)tVHk@aKLtLb+o{^}7s3 z3y)!m5m~{F?iyXKK?kj#Y{Z(YACw?W8ijg|HrjLvshz=fGv%D|oEEG21G0gqOHzi& zJm5)K+i_yS--)t!2Vpg4S9AVd7xSMl=J#b!_O1BEHYzUuTe|_UOpyjzNY&Qu>2jA# zWN2S~F6fUnZ&&zK<{M?f`F8r;V8}sVjcJ+DC^cCn+o4nT&I3C=X8hbqLV0$%XI>9E zSy=-0W43(rp)gxZAnVm1VLrHW7_ZB+4y?=RC#&30;dESYBXBI5VX}*tQUW)=Y1?1i0~ZSH?S1s;2mGIxfx2_@{ga?t%fF5Ph=O;#3IP$la5Hjq znKH=*iTP=qRyAAA6FvpB^hBg;nPEsBr(zi1*G zk`D=FDVJ+;?~x|ad;Vd+0%E#WT%V~S7gN}N&PV@}b2>^VQgEAow>@V`mYmH~n_ z4OYd08j(IC23GFQXt(*`i(Q}ez{TIDSJVIZ@vQ+-25#O6p1gyD1gFGPkup_gmsWc| zC{dfCKvHh{`1$euD?>Jno7McSm-`=+7qNjt#_=*bf#i!p^TUjMxy7cP;K%($B#w&K+o0naCwqTpY-0w}3c&R!*VH(VN*Z)oTFj za-Ww3fnEa=8}GlEb)B0KMq*)jgj~!@Y*#mE(rf)&n{j>bNKLVHZ;cdyE)k87kE1y_ zd%ABL9uUyM1CMXMenTS@{71fUVc~!n!EbTz@E%>O233aNjxfRw?GDNAc!iWoF0rbryeOHeQ<=~6?>6VUYc&}T*{=J*R9IGN)P-$yRNN*+{e zlEy74B=WTdtxzQ|iem-PA!{I92pyQ$x5{Ye=2ltk^&cSt9yH}82=+)GTtl8gL6+bx z@I4vA<$@P;RUJ6@&MnT}bc_7gaiSQZxm5 zmI8jz;w%gc6Uqu2AuxcT2KmT*B^?VBQffjLJVfaeh{T@PbYzn#!|(i>ssD?w$caGq zHJjAc+}jfyS~Y@ekmB_G74g5#!F!(5{K`WznZG}UUWNdRe7%;JP-+%P)Y!1rq&P_B zDZ2ag&wN8pmU9!P8R%JilW)@%MM+CQ@4rfD9qZqS4>itLIX*ivD+L$vdxKk-ZF}B? zo%!VPmHu4s&EbiT4tDrhGVA{|;4r3iD#u?b*%lYggfCYdm?2RyyDw@@8~HmUI(Sj% zw+6lbZK_rrTjjnRpw-9YMtV!$tu_ao5sQGo`zUUtbIhFNT#K3SzW*@Jr$U}R-ra=i zZ(qD>Pr{4Y9JYQ{3wh1hXdYuE5e}=NiG29rpe3BE5P}fhl!lKuA1dohk@axaSq7P< zvM#dpp{{@Jr9Q;Q94{W939uNt^Ks*;nHbqt>8>?=3KjzScZYZs_7c@J2hfxe;Ix%^ z(j-p;04`^H_T3Eiw@mK&;}_X(iukW>Dj{7CP~HY6lIpCxDHY%VkM4-8cd-8Wdk!n~ zX^Sw9++8i8Ph`a<8GQGhe%8ehKt$pmao6Kv8lS1}*^zIG`roS_v{gz8jcxD4RC}md zJ{S*_&+lH!psqQ#&gj3-SR(H>svz!Hrw3+yn4Nb3h^B;S8s}+#(~_M*gYejF?b9@EU_Ha7E-4w`RD~K8do_pA1Xz z)`uy`RZ+`K+TsN#k3K+ucj@eflBh9ZL!F1cG>dMgha2x+Ji@W<`Td5DL|!ohe=4im zlakYF2oe{>ewv6;mIWLK@$uJHyD>t_B*f$(`dxtW`XE>loP{s7zzQ^Ft#jDy4Fezh z#?dN2JD@Uud!0$hg4#0c`i?_u)tw-=&<`>*Zr{E81ZX4B2?o_R9W$vd^g{#X`_DN! zEgrEu{FV8Tv%WptAXyU2il~Fg&D$xVm2riTE`IYcSR#9;8p-cFe$D!OmS&>Q0WFc? zmAcrMrWzuwKBO4y(ph+cq9@nuQ z%CFJd6hP#R>7w7h-&t~Dcf?CAFWnmCMPZfO7FM?VMT%3$JxSF9Ei)^4nd~ul=SgE-z5l)qkf3{LS|zL( z9g{x?(%*l1m(xBFr8TTk2FgHuf(>4WJx>xiFH^~6kSvp*s)g3h74h9aAE<%^ znTPcB*W+EMrD7d1dDnl--h;%K(ytRPx>52!PiT&<_O0EhdS+#r5K;(-gouR<4|fgCuJb#0yVXz|1rvkiEFWBz!y4#<|* zm>1PXZeEknn)9AA1uuTFn)4G9d+#644I~p*LB|tZSC7~!m-24T@^oUVM&DCo#@Qfr zDCLg7Zr;oXS3Rht^Ijp?(qN$wsc~6SG838Z}|fKrs#iKe`i zpIL{Itww`>%*c6|;$?_p5|LOBb3esJt(FO)Y`1oBY4yR5aK0uGeXPTj58(}RE*d*4 zYuCeFZEsaW*xF;;wPQF+R_ps1SAaj%pti0Oi(sVN%o& zmJNJad1fhG(5nrlKf*w(3obo}J6Qv%B`P6uOu}6-+h@kx%k<42IEZguGdy_c`|jJo zqfu2~;a0q(7t$Kstsv%Rb7yB2JyR3hl?TE@-l7wqy3VV*mOJ)?>bSko^oU&o{U=(e zYgKQnF)k3dnyRhpj8A)ZF9<=-T!_?@qItEECF~XqrVq%|E%o8FNhiDnKS(9Y@oeRT z0HTMQ9rQeD3)QcqoL2XWe_zuVs{WN?nqT!t*V&SrsnCuzAj)_F=8P`*yd(|Nn-l*0 zPi`FyB&9we>+a|5Y~0lLlY`}6Uq8R4(~Gm8(XwAfr>q=aG13niM1+15tBqt*=v#dl zOGzBGJlvC%G%JT8&+}{qGf*u#F7>iajaLi#ph)BL2ea4chmX=7s{&lKuY1ai#kbxQ z1`C-nt22;8B-x(C+}?6k#u6>QeOG(5nD;D&IAQ+2&OR|}7LC2$lo)F&86wDsC z>$y5fGiM)vqKX+-Hw36Ld@MC5st9i&el_`Dwb%L>R0AxiuUxVU;tZy=L^^F_KVu$03Ka>jgPL zCWN*e3A4EOf1XSOshL*%f4c?19(dPkiq@N}c5vsTC7FMZk4Gmbqo%g`0(I$0@IUfS zbr;w!PS+1@Ir6}wHZcVuVYeRc!D-3OD@@{8bamBEM?~a7oZ`~5)J*(Ie0lmMq+&oh&mPFc{$B_ z*OPYha-1%-g87l=eOx_R0wW`G;+~fq3R-bs>_Mb17L5}dR!{>OEqj{gV>(>^jJSaT z4bV6_=LI#Dw7OQ3WBP5>gdya&fBKj@uLQ(y-exVY`Akyv{60$FK`%*!(T$rNafj`1 zwr-UX4?!=w#eBRC7_^5RD8Jj$&qnct0fcJQ33{WjXXOOn^2rRQuAvHCimq%gc=`KgbYW)-Kt7e@hc zDld3ha>n|B-0cb%&*d>exb_Z1B{@9fH3bJMQndPLxEvhfa)l5%BO_fn z?P`$@GDSIl#uyEc+>zP-;(_egzuH6$ zu+RC?iahMep^)tSPYduZ!7V>Y)q!n?^AxBI!BoHpP?anIc`j9qGI`%smk_bcM^y(* ztn86JyA<-r6wZBL+Rcw^ryk{`JxER&t-*$bWsWMA1?gQ%ek*Q{iA3FIjwLr75= z^<_0aVndf$-o-H6*Gl#Hq^K(!Iulr46|V=HFb?zH^Lj@pn}WI)qQRt6#eV)Ipp`c) zqK@L%?-vgN8-WA#dk#bZ*%?ptn0vHf1qQ9c=T{j)cz9jN)lp-4JTfVJM7~F{05tWO9Qq|jVG64bu zh!r(=yv~vvPo2m}903RF?EG+j%gqF4`}R{=KUOhWCC{t5F?q{Yd)#bhl4+%r>c!cc z^t1%@yFk)9H^(^Ta=!-v({B9>Pi-$OmJeDcDqKXkn3KQK=8+nvAUX%Pd>P_Wlcvic za*V#J+cVnbDpzxO4yI*>!Z3hBm+yY8#gm)cVGEn-N#5~S1O-y2Axz-Q6KW`C=L_(j zj-C7?Q<)eMG%@O&qG~OTPu`ViFC z)ukkj*880fG*cf3`5Oe4bdFh*2FUF5NNV1FKv=#oPfI_q&x!e5)H;xKW? z(Ae9_duBx{owzLul0?ukFNo>(V;&jJ#}G`+kn`mMUURR%-UnVS1C%P$EF7rKHt(Sc z@_xHV9a0kJrI|iT{}bod-xZsOTwS@v26JM|GJRemL2l}8Uk4`eeP{rSMA-@Uztxi+ z00DkK4%Y^~+9&eVxjCX9yTGR&g@>N|n0ALK9sSm=YVZ=I^nXT9-v2OA@26a>iwW0K zKp(FXvVm$0qK=I_nzkmnv&*io-cqP9-TyaKhWCR&pHvMGs`lF<>2%dT=-^!*r?Q^R zo%5-UKRkO@4z1&Ld_>Th3@8o?^zNms4KBTr8mGQmdhFr`^Y0)^2PM^mgl{MRJW@5e zbAz___SUV+DtrhQ0Ga>Xc|spYj&C7gjVW*0l&HU;8mz$g6_k+d^s~Wu73&ueoVY!Y0$8*a7SdWfbD0PAie z^N}pvU-TaQROcz&U*vz#q`SDvo`T7ry0$GIkjQd;)8M~u;BD&H6YOp>^{dg>#B5)S zrhk&*x~-Cya4X^!tyVAX}}22!oEYU}#&*Jka;)pH|G6na_+ zYzI3ffh4dsMD`FJyh{B1Zu_+BMh2k0%sIML#JJ|I-W)kO69&4^GG(9D(!a8bdz2EG zcD-RE1`D}Q9VbF_5>A3O`1eMPgB(J`3$Gh7yGfEEU_Y%i+$t}ksPd>^y=0+FNsX$M zN8*g9sdnS$o)GF?HqX8`PM5klO~~6r zkdF9mQ8tR;D$f;Hb!%U z<)F@Ii&z9w^@7&c+wJqR2Y&B{Oq)RLtT_lvMq4U4%U#@#qv5j$6YOAeByS0zI8Hzb zj@Pk{&fy)jy%q+e1-xjX%)uFyn3y;z?`x&j11>vGwtl`pu%MLe9H*4);$*?kjnSmc ztXr-wKIV4~%*Xv-#jKRP5h;>78S{OCo~im{cKfngFC0N|%!2XE;OYTtvw+|k~c2P#lx(tG@ZRxD6bT-HGgJB)1LHwVme;Vv z2J$HHh9R-&w7E&`ANz>j`y@VhM?ZwX{KrDb@?(xaV!vqg#IA}UkDWku@0jN3z!j?$SvO(;6 zJuu~oc}KSCJL7oZd=E=uqi{l@1n zpGzoelfY!RD^hl64{NBewRg@4r?^zI`|rsNUKvxxB^+yBPglz1ji^a8%B?=d#lzd& z-*?`fX|(d{y|pvjoQNJ!g6=-GMSCVhLx*x@0t5D1H#m!B^G5E#^D6LNoN#NynEiLSDrDrbB9>Zg=QU4m?Bs z*JBQpS6~MR%oaJNRHyvrPX;`3kFk`Ze~JC4dFw>nwJNRa`+$2%e{OR)LTo+a=k5^W zepwat4q;|Y#0%Bt^yyy7(vF&$nNjL2ZE8vfggO}NpvO=wAP3>2Y-rO5(laOv#LPBG z6#S0AI&AvBT7LHB$Ct6Kvc5@$GGeOhA=2!&;d;qp9!1vk)J0m0Dz0!cm{kxjvASl* zgaB$U;(NN;vzfEU6akVZxCq;ya^Z3d7rEXzeB##n)kYh!21CLq%0ds4QGDfREEYU2 zjiRE0@-mD-P?aay>>ZsE#*KVM`|l@C*D9B3C#Wt+2ZAR3UzJ3XKbvhzP>Ca*S84}= zwc)Fu!QWtCAMjH;^h@%PQ=*JZ_(^{X7`)X8Wj~4DHH|j%Yl(g(kH6znsevpQuQpwq z#;vqOMnXI+(*Brv&z!M1U|t@jE?&fXO(@myQXV>V?BDiZ!`s2suN$t3*-VFLfaCX$ zh=E$9T%fx8@9~60<2)xZSwWawSaM)E+%A*hfzF;<**z%(Bcm^9U~MH)PFGKltkvob z`n?6HAliEb!zN$}$0qpfiTuEgn(QG3IwTXoS8@jTsQ>KmZ-6N0bu>V+W6>d}rYXU3 zaK~3A>HQdvq2a4};+c2ESmkjQ#GQc(egvH^X0ZKOd`5MCgbodbQtP7*>3J-aP;9Y$I<3pc6K_lAFa2!2&E0^jiT=8;}qz`l-1Y4Rgx= zEgQL+1Rb`#7(?7%|{LK`4h#y@*~b#l?8VsJYeBgbnix_XtR&}2} zFg9ah@QoNI(xZKEk;n2%3Nz`?vA)M}SmyeyrH!K>Eewdp89%7Nc$7vr&}*ag+nNC`{qUSx770= z-Ac`C@E5OFcsdq*`2^fryL+e>^6G$74>^#3b-y}Y#jr;#4L`dH>Ck-W&WNUB z)ri?y^{!rP!PFx+;$trQ^GT4;9wvzLD$?R@L4_>>^D~aoY8$Hln2Kacdoa75DD&jCN zh2ZO;e^@mj`&bF$jXzvxy2jwgV$6Yu15R-WOG)Zx?(x-UI8>3@5_V_Htf8&9eq+V> z6c=3wkp$-@Q4Y7B%#X#E*>(8Mrh74$9DYCGh~F#P%$TaE06?vsn8c?J)nZ`CRcFHx zz;GvR;2y`iMhukVtsk*5A^vdskB>o63*D3Zg~^2${uvd|_r(A%GFe>lTaY zrr_;ULG1-lE=K0Ynf-g>an*1DcqwB97ORoh{w{Ecx(U3|^yFZeGjTfL;ICQm<*m| z`a*&bm7I*TT^bzvs@efFMz-UXpr1>&CCVA1FDC0u64Ksma-gMxaY;0_l%-FQVG<=; zhtFS*9wN`BaWtCrq7&Rd72utHuakVVv7)Z4yj=02Ob#nVxq2H%$P~=iiXRz26F6D@ zD-#zb;Qw~kr-JJhxW`%sfGM|(4&J7E$ISNYw8eFBMd6*%7Ji4h<`2`7%MKd6bqBpN znBm#_;1@Ih?HV(`^)EiZXQNjonaD7X3Bc#NdfC+{LEoipU^a~B7J9(XfwmjUGhSNG zEY?SHQ5<|%S`ahzFMiXX9o`(oHQ-bsz>g2LR|?liY6R<|sFlUP>j*Q-Yc&5B>=Wy4Gg0T%+5EsKOBLk0C$xH=!2Fj!lF? zz8asxtP~W~k5blf^EXY{uup#*-9;-n84v}r<>=$X{J79R9s&`NR(qHduSuf)vr!P0 z_3)!^)~_fYp}q`BvQP>68-!+MG;nd8Pc{-X(+nKwNrU9JcQD_d%*IaKTYz_}o1igT zYGzY6T~Y6Hn=ad(O>oQ4%A^+r@4@MSjTxc}i{^J}W@cnaZhs#t`ua89$K2F(>U*oD z5EE%=&T@mm&s);M^*l@3!;<#Pl3%JQLmWg)k9}cJ0~rD+mX!G^Qaj);Xab_?AId*^ zulQUTZRrfAzcHJppJB{;i@Aj3MVTyBe6itq*{RK}>vA9Pw~0_R95y4QDSgO#llD=9 zmCrQt=Z-xlh_tFI!!qFK1}C{BE#rffYlY)gkL%Eza#%XMeLG+(ISQiIV35j7eIw*< zw*~0mV3%7CPA^|({ir65tfJ`uVa?3IgtkkDKRF)yVHTCXx4=geki)Kpb#n zbLJ;E98WqwI3BkFjp)wrlUb*@7E4LS9Y2YBXFW^BS9F2bN53d9@>r{-l&V-s*r)>1V0R6AZOemtMK*l!h96VO6MKe z5;$8?t&300eYrrJya>!*-zfvaXhE@-W5r91@0ExiB15v5C=X_+oCpPJEx8Z8Ni=%* zhKbO<50pIm#)aVBHv9cJf>6?psrE|cG*+uqZ0 zd|3j{17yvZ`Ql9&T1C}bm_9a=!XVg~?t*Y~K@Albo*X}029aN>FhmeA(n2~7!`@Tv zJ;#OUmzO`osdHo`f7Ybtp3BS-5TcNmBx#P5uh}50^KIf6?@?5qP(G*lYK<{URYUWQ zt`d2I(Fp0?)cm1e&Nt~4O&HimO4>ac+HFyV^#9#|smr*w!VFatU>Hct2EnwT%hbjd=DM0K`?@WBs)W)4PgN)#?{3{0xK%C9UdFrq2nus5GDlP#P15J! zg>)QmY_`Ph7*Cut>1|9Ntv~YmWeGWwk{vBu&-q=MeFB{`LDWhVA7t_B3Zr+6T|0i3 zb|P^(vlQb!7VN_WK9XEf|98i|sH>fD!K{t{?7&F!NbwTthwu0~oy{+(KB-)vuU48< zH(~rF3S04OnI9et>w=4&9z1QlH>gB8o#~&Z2@*4|^!-JuNz7Py&d;>RaoJG8&sx^n z*u)^IQ~gZyyG&kO2W^xQ-?KO|s34y0v|@*%s{(8jhdWH(j=oL;9P9g_h9r$FR#S?* z=8PAr@~s~kaD0#TLcN)_Nv_Zj&jLqNUj%ESwnPU7?2yGIK|Q%+4mL!b&x`rwhf4C0 z+ApXm6<9aQZU$igG#Ngf{lv`>kRvK=JcF#>nOvHFk$8pvi~k&SNO=GLa~Sc7iG}KI zO^N2&=@VU+tArx$LmcR&>c~AbR=R?ShNjhZ&PcA#4I?Z#uMo*w z(ZTg15newjU>KtbT>@!oPaOZE>WZ7gx6Qk|B&IEgkCQT4lgg+ zdKyMME2|ogwcq5VZJPS(Dg@D@Jp8D^QQ5BcaFe3+*Xez@9AF+p{g}m6cVpiGp5!?-E91wcHJ}C>|3G)BjBsVEVX) zDi9m~IdOc_%eioEOdPC+Gw%8``@`HG52;fk`68pVUi?S&QRu^NYe{PRcUSlSr+IX# zKf(CMz;K$JZ8(ZH^KazPdcFaV0Us?k_vrHSfiK3Gaj!*;epXRobDxZAc!2{fsyi9* zy^1zg|H6>iQDQY2a+N_wd!uAgiVX5|DCIvuo@{_@Q@xG8y6NAGiE67|9P3$D2mo(jL!z-FI znEwpn6^t!(DboszJ^RH@;}e=&v!_4?pV+uJ;N2cIlJnCZ=oC1g`0s}8>aE{Frw@p_ z-U#{d>y-BYB+88un?yLMhm?@6)fy-~$&5cHbX97o654;?K+@f^MKPBmeGkGYaCo`? z4V{{K&v^1ZtAg-yVPLzM_Ojssn6S*k=CSgVNhJ6qQ1>`3Cb7-zJvIE;*yh07lA+WU zK|si7%rK;IAIg_XalElsMML#~*XU~J#h4BX`w0*b-P9VXF4wXNU2_yj;k2-k`Tz7r z#*R{~#>d;l=EPHUX8c+xSt-);&UzuJ1^0j7U)uSr$*DPphNBLSIIz1MzgKcGCb}JS z5(01u#$%gm>RQRJ5;iYH=yAtO@u_w2kj|hyJ<)G1)WKgP0W=OHZ3GVv*?#_U+`>BH zv)e|#gebeH#|56TuCOe;nk?}1%2zzYw@?bO2&ZLzLELY-cge)dx>z2?w?t6dholqn z4amp71+N2|MgN;X){kudcK?$?y9!N~u4bs;tAcY6P*rj&xRNwMW{2->m!%{Q&Zk|Y zuw$HaaO&M?w*)%bo5yuX+$(&#hZ|ULw~ET;E^;0}I=nnM>;eNLSNN}o3-{WrT#nx{ zYZzK_4Zf;xTRye1mDRF;-!j_mQYG;YOKZFcSYi3d+}b}P(-uzG-_z3uOM42s(3C+V=yqv%PI}7BO?Xu+-{*WH#l~$9dDZgluR4@9DYiJ&ge? z=r}vy!}?c)z}P&hB$dME6(G<*uj?)O-*C>V;EX&_cP*w2kti-$lhG>*LePl=`)s%^ zbi5o}TCU&DQ^PJH&H)u`XM#&CdQQU6Dk-l33NLnf>b8N;>UQA};Xo}^lAbK25m^ys z9?euK879bf>=iD}%Jl#p;N`qPVIXk_OMw(`KTnfMQTB(Yjur|QbmoL9C*%&&``iaq z>2#mysON(Q4&(cspSJ?Z@|KpChQmSaX<*WnWQygL?f%~zNFPv4ih?e{=yNmRwA*3@ z1IGCK_iu5#ug^!YLf!*_Y@gl!jBsbgkv7iOV3s-h!lvd;e$y=HN#yVgMnhRvOkpet z($l3s7zXP#JfDC{@|Q!n8f#ow6Vs+}SyW#6fF=oxqG9VCGk1P87&c4f2roO;l0gOI zJ@1dq@OD)-<2j#|3^4lRBgTN+^^VD50D$dF)C5 zW=%VJO18&^Pje)y`;ysJ%Y9VgBR&^;h9kW9yYy#o9Asy!O5fO`^V9dF1n3+iu{FO|Xn~l){>zbI7EjSZ+gGAdDhdtUkhb6X{)ZX) zf*e};#6hw_C*w+Y$OJ4${2+W;3vc_`RAqOkZz-^|GWS$K2e(b0~KGt z&V&4oHDE(vR68(aJi>BHHS_={?Ji6ji3RCT0?Zs*EV)Ibnhzbn; z|2`3znxK(k4PelSiJo4p24CH2tBmd_!K(;ysGz)f#Yr(!ZoEWV zC+%1*{)t!lyC^O)=5Z8wy2c8H(N3U(B#++Vb2Gv z!&aE!LAGAu9r*ETz?KcmA^@h0x55riALtbx1~X+C0_X^9kOsY9rIZOEe>;ocw$n{MU7W?GtPoOqnU!+9LUh5j;{&W6Sby;kwWt&*E_dnLNe zUa201h5g~o9<*g;f2zUk64||H=o4C^iVMu-uoBzJJ2#hvxwKm})RMcd z?$GU&qw9dYAoL7;kPsDt`~182!jbnZPH$YJ$gdSd8M&C_4w`Vu`^U!Gfiv(~t?SJ9 zPtHP2g2#*qb8ot%2|5P!jMvKZUp*V~eCk*`2||RSfjd1E0gz#DFk`8p&imMD8;*F<%UTm_nyX$`s&9`t2X7VbwT9SLN+#tM zzvQwF#E0d)L(mSXqe{wG+$XB+E&z`w=j+#KASDU>T4M)W65mg43!KYBpmPmJw=i-ACbwFgykD@LbOt2exmt~O@^xc_&{+iB$KaZQE8Z;Vbom0P{SsIh z92Ib(9slpcQN8^xfXCbEB1RLsINaust+?IHz>Ze9yugy$B4ma8_iwnzzKcg{ey#F$ z$Si;gHVuFbN7i7W3JWjM=dS+1*M}4rj1})mipwP7W6}UR{-S-7?nOo!UBJT%>mtoH z4s=rX=L%ehY+r8hw^G>{8nWwpD!}q!JuJ05P`@;4>d9=cXP^0#J2P>>=nj6_*WfQnhr82OSX5M0C!nml`t@Y5IDPDGMJq+R zH(@rllmS@z`S)4yZ$b1jq^@0Om~Z_S9q7eMkRTuwaITfk=iq2cd&qURqZg=s_6Lh6+dzYIGbMy*U5?n!IHaOToFqp7xK^0fA?Y0= z>ps+t*HFt<>YTQFIcUai^Cv2txRd5J4UqMO=)05@f~zdR#o8?2HhaARt|vA*@eV8? z5uA+gOx=E`fUP!{S@emT7*M2scO8Dq9y^67tOC*~Ta#&sn4Eu-%3*~bF~>@5R(FK= zErb-15pg~!CYS&HBp4x>?}2{!`VkIsCSUAIKVg%E1rc~WqO1odL$H7^wV3KK9AyK` zo~TMvSC}*+*Qh$@|CDc$IGoEp>Mv7<5n2Jk&qEExUkLxPKSvR@X_eCPuH72U6_#1Q z*#7Mj0~GU&6z89T%iGlHaB>SJ!kxzJAdJ}wpkvV>V@(h;<0|32PjbedvsmhD>%Ne5 zpS|M96*wbcG3OOIf&WMAB6Tmke(7z67BSl{C!w+_-tTSLT2SO&*yOvQqlnv0V@m`>6{rKP8Fj-*w5^GxZeX?p})V*j- z4QKEd_-x;0drQ{AT(!PX0n>YGDlLd}^byFT6-P^-wU7fqwbSoP@KFQ}weT5JaS~f$ z_NO_rM5nT#Ye1xPqggW_4wpj0#0jqq*cS+U=$_uCeR2UOi6+%Q!r9txKi%BRx2T~W0h$+Z^u0O2$ zFFvsj=f z38U!04^SW>uVX<+t>gw64?mvRp@wKlYO+ZT6$WoZIc?7lDFUR7aV$`qTRXsUYoQmrx%ld-n;gcDjv`PN{qteU#%yA4`9ZF(0^7Z zhk6bq6a0VM)Ta}#gAe{nRD(n)aB|fFcPqt0e^}0zmkb!>S7?}lF*7BObgzX5r6b?Y zof>%nBEo%RMAs1N zu_;Z&MPnFEB(rSp)SSuK!9nzeg@zO~KF#)c^IHVs5UDTq-!H`1P0(Rqovii3&4)XQ z4OH&?jXDKYVfdtxorB+hX0v5bD$HH`4{f;f2TrGvK8-GRw4JK`WpHXu7*`l&KAA&J%zq&OZ@`cf!&+Ad$0l^PML5Ma>sYzX zhhAeajO+B^a7Vh`#?P}@#mW3G7P>S))qdugF zxW))`jX4SrsdX>ZOLUzB&06&G$sYQ~D3RPiOYSozW8 z+AgbDWezY$PmL%QtQuZ$C;eE@Mi7|hQ3W_Cg;50(WtZL^VCnm~39Wsk>G_=Zoyui! zIUkj&i_Yh;GqcPFK|HVO`idWMBs`Y4ygzUc1IW%!CL+wMk zt^(1Oif3pW@Enr;dwZ;LV{Q+y^YlFR4{*5A;3y7t3H+p+G<17-H}%_u!yMo8pgHg) zN2Y^CBohiEF&Z}l&p_-Ysa>Ds+rwG~HxSu)@H!bewp=DS(AW0brvpcPVn z4f^`n8npYg>JCCo*x0vsH#x&_D`G^d0_Ag)rpjWAn>Du1Q;=yU4#hwPC;j`4pfv;z zg#nKk7Io##PZbXfj)c&wB~*bHyku?cPoLJ%Oi5^QY)p=LqWRx1#%sKtf`;41JgyKE z-uzoabvY>>2(Q@spoPlfBSj$Ou^dUP&^k< zfZM4?8i; zkcNyWiG+l`#0EGn8XmZLqonxBAW)G@`IcB-QGL06{Pu_ZYUV1pr1fgcL^xKk=HEL- zFUL5;z#T@7)s!-#j1s%1D`ffiYb#d8KnxE1l^56D*-0~}b&*4&#VfBf20WQL?K&JeDlD|L7-c|{*r)*VKGY)cKc$Hl za75HFFoim>jPED-L!DnvziPkz;0nEnQHg;w2_s8%Da3D?kpM544Xxf_TH+tGr@H6n zlTMzZLt$7aW`HP@3`Rhqhj2Em1%bbJ*5c-iuu~+WTFp1{w>4R-EdZwQD-4Od^x$rJ zv%#_m`s@(rh)-eJ&Av zAn^cfgrik=6iSXNb0)&7Ik$%)SJe_BZ#hE$JhHdN>Qm?-wyGp z#>nuJlWhk8Nb~*pKIIFt$#A2c(z1bf5l>Oe_REuI&9}eH%5~L#?m?JRWUmQ*+97im z@18M5HxmXi{P#79*AalmdSapzWLqedz5&O~KS5luo%{fJcL!}zq$8nN*ZXZ)-&MSx zGU-GBqiz{pNIqsD0tTN>N($}(bcj*Tsrkv)`l-*1@a0!aVoBiC@o&CHAEnDVKUt^s^Smo?-{h1e=(GCF3k{BTE+ z=xSr6gn^M!>3;xZ43d4;XOR>`Spd#rH_x~DEe|P``n}*(7b|Aurz*5jeRi)NrzlbR zis{@EvUFQ*W%$&5gP-ujHoG9zZZr~BVU-%7VTU5dCbf|vVbI6rWSeu_E^Zk7MzspH z;D`>CIMTA;rkOhx&^-AnvUto|Mk9Brfi``xR5`CO6J8|$b#%}t2FZf`?*TFbSOl$W z#1?3rJs+l!xWFx&WGya?_Ygz6!Pq|EbAa0`Z}~TW%)%WFD2nB{e=k&^M7fxdN~7WH ze37cxux~M-l*m=UiEcH9;9jL+v7qs=5I9m$Tr( zc`p-@)-VK*A1n<-tW%Lt&e>uP>W64|-< zhIrOpfcs-`bm;2bM=?M&38mTP+ZJN?ff&)y7flO`CgQS^?3#@%snd!=Qb zf*QA2#Ukb@FB)@zeG2mLjq=tLi@0ts&#Eqapb$K+7*t~=># z0C~_W7mwiCymTZkuR6tkVown8&HOv%a46^i&<#xAM!@WY1x9Qw^9qFb_r&UFTp@D? zT!bD6bjlU2Kb*yN2h$|+TUa6A`&f2^s(vgaAX2r=u!Y+1bn(#Put{-}eC6CT4G@$cYG>394}t z&%o+CVS-q5MO{c4{g3N_{Dqfk)tLX?0#F4gcu1h64F|>fDqu#f+_s@f`iw3LqHl~r zUJ6DV5k9zmxBQp&7ZEho)VO7%p+X}`(CF=ON$N;&m0|x~CFjZF(t+>Q&hAw#m^J8i zo^J!IHD+W1atvkybd^tI0FNmh7(H<_w^1DM*L6(b9ZCl(+SO)aK~bpNM`|TP=)Ke? zj(%DgaA^`2G>0_R+ZGVZB{Pl`KbVRSf(jm}ZoI_-m`@-nhI*HGA;;{>_y z?&}NaD`*hE4ext$C9wOoNK&W=3-acZH@hn9Vi{#*|4s00H*0P$W%dwH9g_AkNTWfcS+c>WmK)_eN_9r z3IO_@Ki?FHl813^qAxD{rk}wOK=Z_=s#9s}10LZ>8^nt`m_Rg*5^AC^C>7IJVmu#G zuU9NTe@|twQ0_2Gd0+xVyOs>zm?VU2*^&+wf z!}0`B{%Ey4JJ`CrWLHqRmHm*9bqK(={b3Ef-qocIy3heGKrgD9mf?pvAxSI$RN21? z-QVy4+`c0>nu=W}3WcpX-@;Oq2-C*dpc7}sj_P?t4^Yz-MLzVWwq$|~O_9OoMGLEG zVJ(~N5ya%a3;rCUpPr^~9`2k%V(l+ogE}gIV1p4m+)i?fjDJZkU3-6AJI?6B4CCzP zGwznvv1l7Y$IFI*wZTM{%ygjU^jQ7#e>nznNgI$O0gm+T_=;#1c1-3M^9X_csbRpA z-s&Uqa6n};07Y8SNXA`BZ-)2(}k>KW)A>rl%k~V{vevymw^?_=Y!fqOIFZ2NSP zK>+0On?q-}$q2;6qOQe$JM=MwT|78|YvaY4F{7@%$$>GUR31~^lono9VmA zrVl%I8ohe;vdsqQOpzWMOE*nAF7++0dFN*KXPo@66-{%3At#CRn zbDym+NS`ntUbsv4V2rp|SG(8Qo|~f&`DlH&YsSDd1LL;BoK(Mlc~?mRVAuax`Ww;h zgX@Q_b&(UXIX^A$Z{awc@X>$2!&Yrd6x1VeK(NJ@6BJDq0EUZ*uQz%vZAKt)#cK)3wD6+fV7{27z**sdP) zc(M6)X#eWpr3?MaU8jjNSI|iG1OB1yCz2Jnev>b69jrnx5Td@rcOQF9msrDT8RMK3<`~xGjyP z)C^yqrO!~C4C|WdQW(AX61Vt6lZm|pzD09d?^WWmN2C2RqpO9ljOmG6nGX|qvl`Ii zTrH0T&-Wheet*1E;eRaM3k#MTijAYJ$ikKPli%eG0M-0Pi;3 zx~ctz3OpOPL4^QbV@$%E!9|T>2&|1iW`gOa<_(~A(^ zVrLV=Ej`}1mWeBxUEH^VC6zCXj<7tkLy5q--)i0n9Gw>J+i`*0qi~4&2HuT`=GL*e z@3mL%yWZf0sq#B|0mMROe}5Uw(idfxGm11b4Dzi0;>wT^m7rPQoK9^|4%75 zWNb4lu`$nzmMzDojY(J%)g_s*9XQvh95C zItVid{-k%uP)p$VpC`XhyTGs=p4o)4IEE-aU>0%KZER z3E?!c{m$IMj0QF^&8e`}KdDgkk6pvmrp0g)xXWX%vtvqUVe}U(t{z`lFGjeuHEz9| zQkI(Eym&waeH_$?cu2APo%Cl%g1)UgdO9^i#2F<0LGPm@12jw2THfx3R6P;TQHlN^;qM9oix`tB0k=VAtL8;{zIaPvd5Y?urcF7W3x%YU7to#y${EzSBEHE% z1+lzAzE8%aL?89?FDNP=zF%RCv1@(r=|>DNda@_AkkSe2U=i_t{jpQX6)m~1i)2VE z@G7L4JW-WNx>fZZ)Y!S~7en&8JFmj5s2=~SJ$Ltz&jL)jen6uD-?`Yf0|QBlV*CbZ zZrSHPP9z<^PT=%Rd*2)XpBJELBw4qxmli=sy#fJ7txd5Q>sR0S+u9}>D zT{|hhZYAJ}*!2iDpp<}3+8j_Gbai!s)de?OBxU&=Uzv;Ixi*ppwUvngr!*LmOoE1z zN?NgE-gGG1#Sm&C@;L!Xj9QIq!k?`hNkdd*l?1J#MMiB=x1-;_a3gdAiqogRcjdeb zJY>-kY@WtHjE9^#*aV=WR9qv@kYF|71~qsn(8xq4Hh;d~eUJGa!oBn<7eL2RW4g!p zg76NyMzks|-_wxpqh52T%)fttjqFjS4@u;rT1fDzwGU$khlsCHHs}6}kK&e1v%N&s zMdBkE`J84%9c7oRLBVBxb+h>mO|1rab&&X8_Ahb+9>8T+$cQlrom z5AwTV!G9PW+(GyVtc~MM(bC|(GkKF+Ms?2e8z2R5)A8Zt@Un2T^dV8E5{FK|;uRKj zYuMddhY-WM{rybX<#izT#Ty8b7mIJwri{)yi(muAD-#a%{U5DEyF^3b4}bj+X}&!2 zYJl`TRSS5aTz&^S=|uypFvum5YY>4oRjk$|SeFK}lAmJ#E0}6Ot%5N7Y3L5H(1#Ro zqu11}2G~nDMCfDRflQcITEq=sSH#>abxw22__oB929=DIUeozFgxr`lv@VU_=jsDSK?G^f(}D>OG*+l8Kh`i^ zRDxj?R93UWH04L!IOFlD z0?&12m{U!W(1k4!4;TuXay~iU`37>jkHY_Hu0AsT>b%qz{EbNfs!1{xMxexSK*1s} zLEp99sE*Zx0MM7#fXkd8r&wAM#BYK-+v^R|g?NjS;4mFH0HEg8iV2ku_S>!g958Lf z40b>vmYG9tBXawN5lfJtn;o9~#4S}UE|=lIUrW{|l2nJsqd$~|Yj0&<$pK)McwYX* zM5!Boa6_PFLsrvW9sFy_e{=Q95_JS(s@H%a&X37NfmVLMbrFo`#W6dtzCd5p5RwU#qP$Fu-EY?IayqLy2v~*DrPp;qrTM>gFLMDpuZcv$+yeCEg#TF(F$0tBMs`VgxJ-Z$WV9SY>!n5_47m6Z4Xk z)xlNS_APr1jE#Bsj{)bTd%eT#;j5M&bwb6bX1Y9MQEUerh_bN=T=1% zXCU^KAq3(xdGr?<*GJ%9po8Cd_rEXaNgc~7#*F7Z{fc0~G5Pq|D?d5B#R?8Mv-0)K(F0QL%LQiTQWd7-reM!q#KAc3jeTPE1Ispbu z1Fmai^XMQ@xC5W2p1#-&)QT$H59a%?=ZdJ~UyUi#dRz_(qN@yA)d9upO_n}u(?C9C zE(PeXp8pdTJ9F!&r(DG0`zaL|ATkQ9>WTu>)1_;N-JX`kyPIv-zI`s~I^5}eNxz+v z-sJIr`SSR#0R^?~>z4Mpi0%Xb7ky=CVb|>somUWt@rNcm{;&c zK&jvNztR0=J2%$3C9=C4mz4ilOGeXvr6;`swz{sIsWW>rl_V?$J9uu+3!vWiR~M(# zUQ;jCqKXW3q8BCuqE5Qd1b8BtH5)i? zLRhwxf3rfGokziKVECJ0PA++t`J(?R_w;UuLFlE7QXMlrJO9l^T-m&(*xMax7D;ss z0qW_@rmlcP^3}kj!hnZ5iDPIv=+i{C!$FToA4Y%}oSr680Q*ldH!mWAm->-9tJ7ao zjW$O*T+}wD2y92FJqPzH% zaCnSV_j?1-j2X(Pyd5RSw2muk;BX=lBTpm_cSqjUy97yoMOJs?H7JbE2(V;x_qHo=%GDoG4L0U`hE{E>ZMn7muj>m zxGyH1MTzRG$#=XqS|4k@E#cLXO?3fz_`k2F#l>T8WTXw8zb*B+Jw3f%%0}uNkJy{)bYS@w!_`wr%ft_@gI|e*8UpYE z4aVU^xr}QtK4H*nr2Pa$VZS3Padci7)yHI2P6ONVzMSqQjJZbT^Em+ApaBlmnhfxvf_(-5~n{g!ZE z%R`>TNCl*<%~nxElj6dFWQLgkzKqo6OIAo~M*1D#8ml)?8)()@LkuY7^u;9+QjzLs zNr|8dd5TXcR9mz@DVVbKPS`n3Os?GOC!nUa`_YQS+O#pU_y+xGE{tVo)K2PSQXPmS zZAmc(QXBLLaqx%v(B`ks_0A>9?xJ`VI)5wW8t9OTbjhy$K51)f1G{4e*9@rNEwSgk z7~zACztUt0lbQMu%i~1I8m!WXTAlg?;eT^fy>S3V1Wp zb&GZieisT6NDT8I8jF$_=%TG4g0Q$JZ;W-MM@H{~Tc)L)q*0toEj;M?#r7XNR0=W} zqP0VFBf{F_qtT8c-32gq#$fWk&SL^#qXO{PNiC!)SsCxY+xqVKTH%KD)hAuMv&6)2 z*@!-QEBqUB22VHHpplWbj=`|pN)ncSykLcU;x(3p*q0`}8uYWUY;X!87>4oY9;VJy zy}xqjFI0*X5yad&+}ua%2f{L8tSa66w9( zLw)h-!Mz#khg$Ms{`I`lh>wYu(XDf(@|N^JQVg6ls5=$4=wBr(xRZyj9Li36svc4W zs;jOL%e{?`-aD-vCWg}w+DWCtCO{qu!o>WR$@QKP(1C(M{}Q2;`;o~WBoM4C>7P9J zqyg*A97VMbaa&SE|Mr~nL?{WF$g-Sq?#(9gSMQj!oAV@g;_uJXNpLWi`RNFRh=x?ZY_0#r5H7dF~rxMB~hMr6n zVg2Gy8Sd?OaHpbwl?rvE3$@1u$8-LpJ|w|&?%Ur^u$%GB*OFR)4RWCO48k7-ghbXC z@Bq49T0=1oXAY%9&dYGH%{zJ9?t~O7`JhfdDf;JwevarPQU=-1)S_Srw3e7B@J2&g66tONpog}Obr>qk_H1$6c(h573VO zn^;Dx0>aYy>q7;^L9H@Lcr3Qj*@)Uh@CDbB9pT_Sv<^bl8m}<~v}^bk|4=gphtBYg zS6}SfIav`7_re_|5V6B#ldn~es4kgqlCV-o{6d<7ghre;FpSBg5#-#$d|*<68TJ70 z?ZIALaKPZ^Gf`srw>aRaET6YK6%>QpcEB;O*=GQpnAw*4y#_48vS`ensrSaLhs7{O zFzgVk%BTIJ9~?#B&A2+uH%DODGXU9cp)omoL-kkX1m53RJfG&>{>#a1K7d9nDJFmN(b?&<{mw3{mT5tB^$Lvk|JjfTQl1baBO@m1H*cLQey3tS5-1+nRjloH z7AtO%#_i9H!MiWr819`kPM>P;_--@*PS*jiCE@tJ6WzRJW=o4Xcz#8l`@GW5&qXq< zW1YpNpbL9n)#V#kCr#IkRAJ!QVIqJ3%{F{`cVnXM(rp$tC<_|*CIDYD{1v5S zMFK^AI_<|ddE})tD7asXgEQ6uu3N#iOaOhVhzlx{>3MSs=rrSNVmQ|R<{?RtVyXPm zEv>i5Yfz@1&I^(wg6N+&atW*hza~Ain4(~2jg73AK8R~!g58Y2WeAmb0=s50axDNu zP2RUSnRKq$1B)y5E~Kb$goZmXX3v)&>N{lV|e z2u!u|XsmX)W8pvVd>B*AdwiqqaizdBtP16zs8bQNFjXGUEGZ*(_S2VdBqP}Mf=|EU7QIoW7W5a;bFpqR7in9!`ZU_&h2Kq0F z1o;BCS_E;eNcCz9F{F+L{A#KW-;iK~@Mgp1@f6FcFE1D72vAj3&n7wrV)a0Oe-lUs zytheRtp#R{<0&_eFXp%`AJh^w-~oeaq-p0O4zSLG_YwnggRUA(;E8$lAe>^ldYM_y z=$uy>KrQIX^E`j1nCjQ3Wd7vcz7Jk%pz#?fKK({?S1oaFBhghY3yLt00szzy=cakeTrjMv2j+}uuY#!POPJc|)Lx&JOfN`_O{=>=H z2MiN1bUtz4_*%&P8q<3xgTFTmeF+*M#@IX3U7qc=^=RJFuDq-z8rD(@UTjXP&Ac>) z;4X9f<#W?_>5D9W1p7S-gWtbmd7#Zcf>)zK9wqN%uRYV>hR<%7E#cytP|hl~xH*u1 z$q^=(_wtAyY%I)tXH-4J++z8N#ZG}<<}_s`82007PMqPsRIB?V!7qh>wdY+u7Bs}x z@24T17jG`A8zz;d3f<40a}ZHHhhm+SRx$@La7r`&*{CX%C25(XtN@b`%+g>RIQN}9 z4htvb@)ttn4^UWO7xywCK4u;UfoD17V~p;Zb78mo(KjtIEB#ypTOO*;$q{Gp3&PAU zZuWkajpF}cI>;QQl)z6twlbtBmGWlbs>^)E91aSRf^Ze#;eH&2+TV;7h&}ob_B4kN zwFI_Fc16HiRg&G^FC=SY?|AfGc0BDltUAnb62j2rU*KXr8@I67C{$Od0<@!m^)5*vo<8H8?O@c^V8 z%w}#~r^Y?4P#YtXe5ek+!58pbJj#`nxLi&R7CeEKUUJ6&I&uA9yc1!GQig4=tsz0; zN~05gLsgnm!{mS#noQy%wg+6dh)8ZM{2QAjWZby%LQ6b&ybQ9ADuB2-SITln!lgU* z+?3Z+^hxj=>KD4dk#WTPKmQ+FZy8n9)`kt!DUFnLBS=ekHwZ{dC`gFX(%l_WN+T`O zARSw}OC+T`H{I~f?K$Ut-*1fP$Nm8W##no;x#qm@>%M|B4FUd#rctAl=5sD%%FI!! zL9U+KO5tZwQO^mYYRD!+?dq49`seK0!1Ue*(1)B|T&e)8v-N7o?ii%`@$6TL>HqDf zcnG59CmI*!`@EmVYdV6J2i>>xO>6PQi5y9OW>~-fV{W?H-KpP9gIO~gDTI~CFEQxJ zpoo<^?ZtBh-0!J2_H5m`14WsjX)6R-Y`9jFvAs`*`Z7J|>SdRE7%a})E_#wfRC2fB`i+Ob@pAx`S8k6NdNqTJEK&8PX zR`$18twN<+qdbK-hXDmRVwcpO=XUk>fp#2qPdVIK=`AVKqk(YbnuZ214Ql08o!$6wyX-GaF-~iQPEy8 zu|QBIYl;Z55k$MmlZX$;crN2__Zp^>7(iE8E8fL$jWGXDnMxUsZ2xlih^P}aeoOyu z?bsha2zjG-Nf{o#3H2-PjwZvke(>LtS%I7mbnC!k3*0*vR#r1m2@Ph6XMq5$^F1yn zmTD;n68~)HGX%JPMAUHkadCSA(oQd$=1LvhPgN5;(b!Bp%#+HerFY$Ety>e-^IYmb z%%Kp2Z;MTHp_;6hM+%Sl>EPBTKLh$M;UH-miF%lXFEhiOo_Aou6A2RMohgRd5+re( ze|pmJ1Q3axzqa6cxDIycLSV-R^CE=J`akaK*fwr6!p6fjJ$V}R6!4RUIt1-%W#n&7 z<F%E&M&}O6yx*LVC5UB1*J6gdgra5Gr)8Em>YDN2_riD zkQz{ppbs}~4{1;An&Uys%5C$T4W`A(1ZC~UNY=>p*)CSNa*hID8LjY;fvCdPtybXJ zvI@N7)b0(ORqYUDdoYA&rXbueoy-Vo0-ixR+0Et9c58J7t_awGZ@SWw%Vr? z-QodIeP>yqj{16x-~HSJTFjY6YXa2K=?)fmiV*|+_DGoysE25 zJ%0tK@?Oo&&9Igl7ScjW_(dxIRbHaAM@mJuCqJDX9~?0W#duyEzTA&p`L#2*4X%+T zH*R?U_Lqg2txWSt_je3y*JqSoo^Qe6QDUiV5_yqeS9#mGmBizg%Ei$xWL z5%hFuzd8KN9;9rhUpsSZ(f-gCryViLxjyVU8e~Pxrv9xi!ai2RtHXz8AL=2A=4c7b zM#|wvMDAV(^N1-861RU!!MICC>h5&wG*EEIa8Y>f(}XI8s>Q=)EMfc}m$$c+TN#B) zCWo?QvJh#p=D(*W(-7OU3iFS$N_FY%0bOE4LjxL(+v%7*R+L7L0zLvcVDvoEn7(fv z8v~C_t;9!$^6XuJ7#sq|=3_k6JsA>P3VQLOj#-f^^_0q)89-ZOPG4sXiza^q&W;>= zYt`|KIEe}^;@cOY?%cmt72y5TrO+hvgs*^kR%Ak~PqLSBt$SIlP97+mwa=E)@c%*} z@d96%FIELI)Epfh8GUB-T!#j==y|XsMm| z01TYTi`O;Z^!os>VD-?_(0>|w@o|+_f&}$3RSBO^dXywWhhV-Ry*+0%sTa%k+`=P? zlze;}qI_%y&YfR}hltNu((@L}BOQKykb@9+p7fyfGkCsf77_8Y*JGv5Fk>hPl!((R zGf8L$oU}9)hKrfl#qtMNXTnS`O+`x~=+)^%jESf0xhYY@;kMv0ikeb5F#LmQzS&a- zvWoz8M3}t(kb3csb!MuB~#`lCo(Y zzs*Pom_(5bKo^wf#UpL+TaYW<S`a2 zh2-25ZGEV97?mK?cQkm z`G$liw)K$gUcv}%>aal*gi_NPvrNTn&7V+{v-=yh3lWPaEtZ05-Te7EO2 z0f(&pd@aO5n9ZX!@qda3mgeM80LwmJ5ZQ$F_v#NO_czT*0TgD4X#0$fd@ImqxWY%c zSTdDD6D9NCWPI_N8?ppD-^j^lYka1v22D1^G){w=_lT7oTkF-U!P2^gevpXs#@P)+ z_852RRWZ)&iOXksC_HV`N61A|F-V7?4NKXoma18B#-2$C0~-_F`V0^tDWB4Keii>H zdWmg91(!OdBDlkaG_BN)(vSQp9oS@Tk5Q2!Q7{6dmXIdeScfENZGM}I$y+D^>~^hO z@6wQ?s0IcgCjs+VdI9Xl&^m1xy6Vu0o=YHfh=H@GUEn zk^x(1J#^~I=lt*p`Xw>FH=Z&L?3d^Mr)py(+wV|lMmNl}mLfHcp!?FreZW1UeF_CF zz4kH74Bh1Pz}cRME$5Z=c{kHZsH18k1eKhfReJ4(Usimwq=?hRZnP4VKmuIaDg-q; zMk0rk!y?|3h2apGe1!HNi$^?W)yWf}4W?B^D>8oB^%ryStq$*3&op(`?vaJdT#&h2#sC^U5^t0Uhoq05EQ=I0wNsTX^<$qj&1|;le z*`*AM_6IJZyjAYmd3AU?nM$pzBenq|bpn6tHe=%3uL`=e=UAtg%%&va!Bq*>yVFws z?a$?jZvzxCJfIBDb~ZUgB)>!mlY|r68pvdQGKbgbW|nPgly=B@oCQQ078dzA0x$8Oo!cU17ue89&n) zR5_dxJO!qw3=V|<7O4PnUOf_k`B)nndHmS@8p%$Ji$+48Bo)tyRIl?4CHwo0cObY# ze3Iz`_0dE7;^W)g1FjVJ&F0ZI;{p6Ji|4x z++JzDIatk0P@}~Uhk{VgWtXPd>ucZJ9$yuwAPiYxW%NzFg~XjWF%%n*^3?2Njf~>A zJRMDQHM-xj=5y0StLbziA?BO_N)#8@7gfAnqJQvjo6g`p5wB)uxR?9uMgvhf0v{dh zLPYD>ig)F4Y7uam`5Zh0{b(@y^1-kO-c-#oIVqIsM7V!28JrNuB7Q-V43{Ba|8^Vr zJ%f%ojZ2GwAalDVFTMhjvEi4P#IMl#()OjxCwW!TTWOncH5!`JeK1%o;-t&>-kxtJ zlTu7_#p&VjAp~r_|0uKYB3wEvHzLBGpRUQkf4z9|*pK}Z-p&Oi7Ww59+IhvrBleX= z#OckRJ@RSpZzlCxyOd~PN1*6S($|#%`k!J>6BHAoEgXi<3Vg4Qe=BM;7g)(!UcZ8& zCVuB^U})HIdpyu^bI=r<3Q<3077hNXqW8gm^doK8{nXa|;sp;#Kwmoe9ot)-0mOmw z(ikMCzoaf)5U_40D(RBXEhKQuht(h{?O`35{-Q{!3F3;2lT!#%rWs~$z~J7VP)Zwr zN9ln6&Pxyu!I5<+8G_2iM=~k|B;vRLfow`%p<#x-12R>T2jU7JK0K?ft%V6XVNL;Z zp}87)SS-kalgg$eB|#6Vfb`k#rF!k~zOd-g{TN=*Q=1%R+6yX$4%?+2o8MH8zbp%v z5RqOn;QHBnI)Wf%N)t@#UL#Xu;0rP;$fr@pKA8`3--`cPeeu;RMhci3yr>$d2Ax5>rChX01 z7+sM_%kM3F?v#d)aBI#5G=Uu1urlmVWR)(o1KBw4lbbHMitZJ++UdbQ-T4=acIXSn4f;w8sM6q?0~VUJ@fwDh#sU4OA$-ia=fr|oxRWjt&dEl;T|c?MQ;2H z%9}Ye>qXt1UY#J^K_NRDu57k(rEH$NF9kAj3fBwcvAs4!U-)_Kj0q&Dp*||aw^bTE z-0WJ7i%YGPj$ydn{;rCSg#(uOUuB5Bc1`gCO~0`&IzuA+@iMyuz1;`IILekF<0opy zD84nS#H%zzUh7u~l4{^cEepfHJ*8f{F>D*ruO0y)q+y6*z1bOs^`Z#?f$`s}FH)|q zi;48Nl>Zs$zwx?5rC z92&EApMjS7hmAY0t2~YqEuYkyT2BxBw$~>fEeXbLz}%tKux{n#s_5Id6)>xYtOLGK zZFF=r%-f(-+sJ4Lh=jzC&oE@UM}zVNA7q}&HEwynMRh6{nB0ns36QZF=eb-a17A;X zEop633c1><@Z^k9H`)_fJA@;P|V1#pQEF=AV5=W z@v@u0Vs6r!HR2aFUeqtP5DH)V>$<_c4r0HO67-;UK2XfXh9^32PIB4QMCa_^EbqKz znMIZI1fvxeUSE{!TwKsj?gnI0sU5_%T+)aJQn7Je_=zG-D}Velgw9xwDn6bo&W5(} znJ4hD%#i?*t=;Md7x`nC^_-_1c%gH6?$iUtzJ+c}lH)=^1 z)>(ukcRy47Lr3z+N8v}T9Bug(HOP7djtM6RO^3%|;=*OOAd=~Qu7AIsbsr9lfn#5m zhFW0U<>+x3M*%_-AWFXhSk)`w!wV+Q$Mv3!$JtUj0%UKt@u%V4L%Fq}@ckj@ z@CX-ufIG)V&$&{HxL6W&k>@sQ9Late@0ftOoT+c!$E+e4UB5Lv;}fEqG}GW zE*#rj&I}}oH_dab$pBgE{rK-2YA}3)0W>h(%=$nIqW#&V?g;?fj{xZ4tpE+ih2<6q zub7$K?dUdu7;zv1a+M0OtDgCEL98)I9+V9oBv@7~BD3NYO3lTmJk_EVmY66KXc-2Z zEV*P&0XDW@{*?sAMZ7?xp#)mzdne2tE<6p9x-bD#CaG*2G|Q{g*!Khyw!V=*=>{1y zkF0JFqY~Z8ByGl9Q6=w6tV^Kp*!NGfgF(QiHA-itx9JCctwaE}7lvI%h~M8kB|_aMwWl(m68}@+9Z(7rT^X63lW=l8c(qnV#oKWqxgzXLUfhLuIB5R zKT|PO9;{1UF8q-c7+#`+gM9dQhGmY4z&>S-lRG(_Vty`z5P}Mg+9ADdMrJ&O5QD1k zdq0hsL@%-G&q^2k4+_3|xE!38C{*p1ClWQ$rXZc?yVO68drZ8eI5+pt33c%y7z??# z7Y$6nLEeF}F(vRR1u`1iN2HSbn#q8Bzm1f;vZoD{TJh~RfT*@eT3NdEG0 z{rK4_ey1At>(sis7u6ouINqn>w+Jt+hJl_E*WQg9Bd6>X<9<+tkwf)g2!~4(sBZuI zQ^Ck^pl1Zqda}Za@B(X~eD$R!N_%CfYirA%eR1go! z3hcc+<-Mapyk2?pC*Xw>Pi*Yw5BtEvdEG?BiUl5H0JoS@s7%}^$P{-8j)@Y9w>t6U zJ?*5gFBk|VmX0I0(a$Qn(Wig%4rs|G%(2u{*8SYlc`KkmGJF(}7)7ZxOn(wLv$B9u6kv7vvOaI#q0gG_s3C zP}d2t&rGXlE`j-#nvajqPtOpk9L268jVL<2%XcYTd>N*giq~zDtl3fLczUuTkl@)yyd&_<;-=GVw<Hf`USijp%;eh^rgGgaMeYZ{^0W9I3F|#1Fy;MSKbUID-#|VZaUYO=rre;tPkg` zCH3YL)J`pcH7{ig6#HKw#HrcWs8d{*RN`g}XITon3*S)xe~_?f(*clpIB(&;ef##; z)YJ)RgSGVZdcm_|{4>WMv;@rOR=^b10ytu6>*!PgEE@(H4~su|fjm*ziS`+g3IKbC z5ezcU%6&6n3v#!t2^RXHdipEt<8S?RcMHZd8P+N+8l;74^`I=tNho{Xuh7G{2vQP# z**-GH3yMzzv(Pl9+6u9+U6wt?uM$r4gU0@Npm?-@xW7MIr3)kSSjG*@Tr-CTdK$u! zJnbcdpziE0d)wDANkWm=WKks$ErSJ-sj`2JfA$8F8od9YNm!3RoS$N>eYn3%_dcJ2sm`bO0X-8|+b1R`t2MU* zKp&QX4P^2lGlp@+pu$vg{5}(->jfU??w*H~-chIL_Tr@C*w?`=%$Vp9=E&LrMix<3 zfX_(dGM5AzD>idIPdGKZ0T@uqAQA*s|7*&YA z&@7$i9=L)8Qvh90@B(veD%EFh!L;av+KpCKzci`rzV7E=@JK@$PFtqrSY9Cfl)XB} z$fe`P`B*y&7xUv+;+Em;M@X#h$RkKy@@{|~m6{X^Rd}hEI4y^95(QxI5&Ek5!s(KV zNW2Q*i+-97wGSiz3HUwTps&l-2*^VEw-+~0osZSh(UH^FCxruE5#XrpS_&hKIHg(r z6thB5d}wWc8BGDT+a#mFr{12giq*^>;tOpUezg6h*SWj8xD8(2_gMK9-qABn67Bm( zFy=&_E>VKBzXIzX5Fe~2r%FpQ&pk-}{iY9{ry1AG&9Fg0&-#htB=5@L}h+Gi{LR zpT>_pgG;Q0Gf@&6=fwoe@*3-N%53;OZ+NbG-zuu5!3GXbeZ@&JEY`=OQ#7x)yv)Q8 z9;!vGZE&8Sy-)~4!){i#Y=4CWFM9$wL9Yar+?f4Z+6C9wLsC6hXr+))8I=1!Jx0MZd&xM&w*!R#UU*dBkw3^$)udjAsC{GVTMS9#n3xV5(+Lvf!Vl zNP`BVsN&f3j&TRBhRjBSb6auDds94@!}&^3rr;oKOVNA?XlG||`tSjaKI;-Dl|8kR zPwQ(@B;)gz5`Ir0ocq^wplcT)D{)@lW(H9NNt2KJjPo7RnEpq5IJVFNF2KEmdfz?V z0q2MprBmQtT!c=u4g$7K70LR-+1bZw0N~a`Af&S-9U8A?= z^?*v(_sp?kfG?KdD^^X*Y3p(Tcxo&-RA3BI_zgtpQ2Xb6GO%)wTq;`wI`?)cws(L} zxf34`wJ(m}B;(fCpr=Bl=^+4SFOr1uj`b5hPL2GipfnC{KG?oZOR(~ELBRcHl9=9Z zK?1(E|36Svx(e(VdjOlC%mi-`t^&(UtG6&9hbE@%$_IUPb{<_^9O+MDOJFi0$SB{>Mcb;;)>?g0_dTIYs1Eywl&$44F#fL6A6W|Rw~PU!zP_W(f`F8U&+O+V`8jm#(7wJpb&oG@Y-*ERwxii=DoKzmjGaH+@c+Sz zk_SEdt+)0jJHXR_0F0G-W-PNrk1AmjXFwx`$<-@dK5X2Jf>91Nwd*=Q(7+2X^79h1 zyuK{=pt7}uh*-oZF`~n}E1%uJJ%sXJ=ZFV&E=)d>qJC%b+m+#SA*N4_nNR>n<;U8u zI4!+pkHjR7(DN_tKgq}at}`sYGyjt}MKV35%oQkOuTkr9Y*G%F+mmY{^6$PjNPj^E zc;S`64`AN*B2;YCrD>+tCI$Wl3*ojbb&-fGI^0WtIokWMoFf^RT`>R9y1Ph_rG}P~ z4HU@DhN0vt8W7J10ubBsUIpJvvQrB|leVc4cv|;9c@Gc&qj8VG>-E@H#biLxLLC`X zn_pth-HQkJxwj>>Bf@7B7#7@s+4t{KBZr}$i03d9OPCMx5s2gn4+%j535$SAa^DWL zAs=3TE&oi4R`lw5B%Y&#lDLr_W2LL-xWe8uRX>T}-_WlUt7}^t-~POMfSyNIiL^1Oq*de!cX{MHUVrLKtTs;fpQ4mQ^IY?a#ht-Wf(!n z;pkE5MX{J=D~$tM`@|d?0(s<16yK);$KT0E-xVdHZY|8p%tUNoc!i?e5{_Y7C6@Jq zIRKGCG5h6@oMKC8u0JP36=qPLxjUb+xMW2Yb|XWT^}A}S6|5$B=u{EBrP=lWj-LexOjvwH@!C(Z3pAoZ7kYg<(3O-=WC)pZ2Okc5PUpA}A#D}$Ans0GgV zIoTpWKS9U|sAWl1S^D`)eVrycsDYoh7R*(~Q%>!~JK3@)_#&@Ke{b!k=j*yO1Zn|z zX8X#9he0AXKmA)eTeBa6W6Cc`wFWO|Fr`}N3Px~jcON(j3M#_RkO>MrkE-9n88eRLfz+dcH zms>I-1vDFo1|Ej1l%kp-bYNZMxwj1KYcsIcKa!$4C>j|oLZhIiME!t2!X+mx&z$n1 z^Eu{AOAdt>i8HbIw_N{~NNMxREHH7sUY#w)vi)a(pgI0TXW|qQQ86@p!m3-wTMGg_ zw|90Bva6~<9OP?z86HFy5T2R=$Us2LJjUo$XoHI&Iax^DQJ2l_9Jgc|N3O1BU>4WD z#3y<)70(|VQFD+fi&l}Pf$Hmb+q(8hCF)=bdC^3qm_V$a~;2+M* zh`jygzwbTvV#(q0Wmo8fo);*3f4CHFdGIOH#F|dS=Fx$EATk7SyOmpF*4>#U49Nz< zhR88ToZ=EUd?|98H^9CefD6RHJ4a4yV$D{Q8*9?ej@+X8T=S>tB!1i{==mv(TmoXpi)sFsd1AGI9yu00V5U4U&^NxPSv_l zc&`PaxKF*AecCY!j@aNN59824JTK^oVjCkyBfEJrbK7mvv3|es?BaMWhUqMX2cV3- z5^O&|;W^?!#Z?~?s%l3BRv!W3ryP(}5x=sBU%Xkk*g81afRPPAFpb(wYecMt7oU`w z8J%(p`#RVZ1y@e&+V1!c+aAO~F|ZlMGt9}{|6Ycgm?NYmZq9s={*K#(zzSi6$az-crEd>)MJAqtEh23Rx6F>_Z#S~gq)vNksl}#hP2Z1O!n+hRF}kP zls%#FxSbYL(gb?g4D6RuXi6Tg2unh;V2kM(99+V5Gu=f5(}RmPckwCqHXYyZu(eJa z#<4Ph*6^@CY;t^8x~Sean_2)2%Um_IwS#a203iXsd};tBYO8=PsI2KgsjoG{3}gZU zHslhZC9iL!+1-zB!mOTQA!?K!TQq^RgPKTdSp^q=bWdBd&i4^BqzNbF$tBmfYpoZ> z)8g7Sa(u85g$scI$I%LoSn{hLG?SM{o(kpoRMK<#M<1Z*6My|oDY0S{--V;l9V(1) zB^s{V791L=Er-41Br&W*db`a@$8!lMdQVAt*CP)&r^336eU=-(AyjR5t2I4fDG~Na zQ(yYdJy5A1x~0}yk}+M39C#)BUhTJ4eD@+PKYlkp1$^0oVsTh#mkn-bch?>83asC~ z`wF(Ey19%~(Z}KODJeZ5MI3}8!&>QIliU0;U;+SRX@GhEl4Ap-aT_R6?m_q@KrWeC zSYDs)OeQ8#P=-8ygmMMs6e^%o2Y?@l@KrT`052lQUI6Vk2v47>G(!bFBnWh@0(qyW z_gz@PK=iwlIyH8ptO2wZCqeg1R^||cb8BUmLAD8NK|QoK0x)&Tr``i_;~vUv`@;zE)s%>m^QapKCEzmGJ#18GtO5c!a!&S% z-l1_lolh+7-M|R_#lr)l^qv*|dGmiE^QMf$0#R((oCFPCz4d{9ci6zPem?8@CR>@{ za%v*_JuC}#fTK<2LuuxIl|d<+UiR?v5E8H(Ee6*9WAapQ@2=0_V3u+)+(C~mbdwtx zkpu$Q6)td$C3+mr0gFXXn9=U**EB$Cc60oZNBTc50GNaVbN0t944}aPG48-?ZG^ZL zikz1SGdoyYU+1zMCI|k5AeFZ;JKHY{s3iu!@brYWwbCTAAB{79D^C7E?sol5tyxf% zNl}5`+wQq0W{uEhvErAZTuX$por0$ zcxr1`@M!CYHs?TcSAG+yrc>{!e?Qs%xkyD{w>2&QL5bezp(%kZ`?)10=AOQn_jo&) zzJ!~E4WK>F)b`JJ@0B)&OBz?d>?|A zEQOajZ}%)cVr_-+5XxGJz9-ZphWD&~*RKvK_ujXeci+qa28$pCfrZa@z8B11;2GDN zVUVfUrf_0nVg*=of9a|~(^&xumj$mARX$)z1oG?zH`ATaf~DqtAMWPeR-@B_zc}Dv z9G{%H16-vZpm0&29e6Mfi_;{6C=}i8~@0>oYnS}OUHSc!gEE}R3(Kk4N zoyQY^$qzKo?+We%u6phf(C^!J2u?kfiE}7R)o~^;?m=av3^dCy(mXTE7q2hM%w$TE z+El6qkBT(Gc(ac>{`Mrom(TnVr~i&F%RT7RJibehYoR#^tp(o>8z>~(4=+~FJj9*z z<^kFl;+2q`%z$+i7z0aFHtCWXdOaDj0PoB!2R~IX_BiyA6gh zVy~|~$YVN03;yK-ncL-7%q>?9NGPAw8>yzH&&RIX3)CO?vtAv=o_&F3LO|@j*bDQ@eLV@(I0s==E8(2?f%*j74Y{N#H&m@>(!Vnr zV(ik7qH$U*ZeML`XB@(07h11xMHQ7#{8?cFru#G3hyIyb%W5zwCKQZh6ifMbVM~Kl znC^&SneKoBW@~zEd}AG0jYt+x)R;t$g2rB`#K7hjz&zxp$C#EY9rBfot0U zNJUiPC6h(-?|LH%EHd#^2D-k=M#8MmguW1xT|<0-uu&$@3;5jd2e^em%aU{AIy^=>L?Aef;BHBA5%CtkMS~q zXfsdHOA2ocsQ~}kS5Buko8c-tP==T?B3y)0#v5cRq~&i%%P~DvHN=sf#Ta|=Sk0DC zAzADN1h+u+oCbW}?1!FDRoMP%RP?=b>w8O0)=qUqr|BkUWS5%Rev>!e1wKFt- zd}N3wgGeQG;={|0;U~VL?ydqOk1%ih*hO^GHCG%W+up5~rW<%ay~uE-az7VAh;Q$- zK^SZ2()lbTh4#Db<>bpR!z*2pSH~%BQIqf90$DtPCK#CjO%{mF3X-RE53=*#H3XU%y!cp5A&MTR6Uvem=-&s39r{bmR)FK@s|J*hk+#}x-o zD@}U+jB0$u-h`V60Pm)mK*LoDZ%&Tyy}<@|0b}WX5$0j+jBGfAVz0T7iw7>YH9g_z z2=_N>YeXCb3CBGTeXobruZ&I(HSr5y zR&02r_$3xp2-2#&b@)!|VS1RMcd#lt+!{t>YV-Bgjp=xtjQxtzl(nt5oO*jZG2FTLf_60hHm z3&yd-dqgVL)bLq#*mA}URi5tx&wqAEMr@<-D(MaeJvx1XtD$EiLta4unc|W$eku9W z#F+d&ylPyV8_Fwj__F+uP+meTN?=mS@Zq8Q28G)1%^350PZ z7VwcJ^q~#7c`3ni{8CpZDCu!=gpI2ap>9QIIkhS-W^&R(o&sh|LQov;xM$Y!?L7$( zjTE)%r#|}4JCCdJ`3Bbmrvm~@z#KRb`O^&DEV8qX&@SVI5w+^4A4AgYBPVLT?3}j|! zFFQTUkq%v1UWRW6IL^`eIjHtqmru7R+&nzS3sj$YoK~FbH8wOHfoy2}$B(=G5mA|+ zJ!4>I4vVLgHwZmS$pC3q=kKR0;4LjJ@9z$MCt5r&48V;Cz4vzP$^PUPg#yX>ln*aU?OOg8;SXWk z58m=x=3S07;>$v{j1}M(*KEtN5Qaym2Oe2vWhJ?o*Jp6S@kvR@6585?KwxhUU4l%B zoP*+a9eir<-*b}KyEs~CUMNQGa+Mj(t>n4VGV+8>xioi&uMtG;^Ci2xj&#iBA3t0@ z=Z(oD&skjYY4$v9a<(16Qt!&PCc{oeEK&QuA~TEbA$M-B)+We%Qub$Ad)UJgn~BQe zce1{lfIDa1;;RGnwn81V(cROvBs(S-@fC zqe+&CyJPSN@9WbX^(?U@%GHexmq{*PV4X-J?80W&6VuY*w@cGzPlfI7lJ9h{wvx;D z+seOun>U^B9!c(bI1S{Sw&3+o2ve=={z9tTjLLDt`Z#0nz%d5YL&4{i!oQa=O^ROgv z2=mrqwVTW1bZhrub!A0LK>-a+)GYxK2kv*%6$n`DnVL!g%*k@4gvCUxu?ze2_MWay zbvct4n#TBt2RZ{JKT@|c}G^5EYc`kE8@y;^;$ zpqkY3OVbDTlw|uh!a`yol~dInI3gEJ}!ry!48^601|Zv@a|t zYHuwMeLq*f#uokQSpoGAcE;Fo{&OdqA!bdf3`x|pOXD8X49|ymBCIzPS$juo8T9hPl^v2GH+~Ysc`P58M~B?^iws~ zJEYcg(?!>Fg~Zd!*6$Vir*8F90tJ<~W=+m{)Ul3H;5 zI_LO>+IsG*;1wT*$p}x`Vrx(}k1KP$bgL}`UojhS9+x7DMm(wG|#;tZN@>s{OM7`sD>* z&a+0`;qfG%KS4tCLFNC|j!yl-jx8sji_nTvMy<%}lg#>Ww76|EmLC|gi}NbiWJ?)o za8~uTw#X!7M_ep^Egl$)@*zat zvAdL2&48uSuDqTg{@x((zExx)2r_xS(0|BlZ*y~F zzde}73`N#FHw?+K-1Rzozh^)&HbWX6*7hKNY|kJfoVxa`u&l||!Ggxe9AUJ`3Gpcu zK8wg_Z7CR=#`+?-#CVD~x|=ka<~sAwFMRjE7bE#UE@pBcw61K%%_P8tc~^ss5T2Zp z1WBT|SatHU`)6>HC-ke|KunH|SYC2Z2|5{>kI^$^pM(|6mpdO(aD(=8kKpK=f+kh$ z&*cJ%T#=oAmWvAo1@Wi6Y%Q0V9UIv4lN!QWOvc(fBEb5TZWw^}<))mnz~s|QnK&*= zUNo|7upLA`g_iuU1?-y~1_h8-h25gq?udLWC7{n75fT9+X`!YTFL1M{7fW1{(1W0l z$1v*7d0IZZA@$=KI_%JY7OTs{YvpLkqv97Un9v-Q{*8i3!}&K@8fC7CzW4VSv{GZa z1aN4xXV1Ien7#G<MNf@2f(I0w|U4wKqVD9>~J)P zI5n@1bgXWOamyAP@?2z5D!1OceqE|l=Qe{ND6uqo`6|3De(UT*aKesAx+TDkxPgfAjVOcW%)EvTxlz5>9XvV{d>PEHP(K8Okk z3hKwID=IF7EHegCQ3`c+b)k-+JF)D56eqdG44En(%zB~Rjo&GskdH*o?43gV>jn!_( zFS2oMhgRIyHU6D91R(=8Uj4k~h^xPpK*7aEarNt?Dx7Y}gLB!qq*@;_JQn&(EJv%wFyHO6R5!mZCOh8`iSH6qUP;=K$OIDkv5@X zga@Jjv14mye9g`6>+Nkf<%Hf{EaqC15iqJq$b>~itgQ7VfPh{n&=?e`XANH-t-|;A z_QG1?&Ym7KzO=F3v+uxV9o(V}0R13VxE;L#`ORS|Da3HV38(pTB{GU!5FhU~5Q>8r z>+_3TIftVaS#BO4>xlxaT)F5K0M>ui=TWZIGBD`x3@32ETn^p!_K!so^Cd+>UCi$a zE+xSV2wW|FFf!MtJS0Z&uQoQ?p6_nDe)F=7R>D?7;MKhRQSrC4B^y8a-?9U#8>QO* zz6^MfE8i@?h5;*|Q~8MMjn$Q#9z`_dzXu>p@C)AuGL%4n0LXKF+|dR;r#^fu{4NMLiQL$Z`&`;PeZOC=6-;Y=#DCp?uL}zpuzqPQypau+P z-4-2fZF(m4%*3x>zaB@=%+Mw?(b+s?1q3{;?R(Fsyx8i!4z_@%k8|KABgcW)Zgg$yODozFqxDP-?>(wJ-2_xbUuV4^3d?zqO0FSk+qeJ=;igfU9p>-^j=i7FN&~)8=(qxKOyH znY^~dXrao)q(fC+u$9>VS=C~Oi%$t@O(GZaQmBBpP(x`ne2cfii#|Vuu0}mgNCgjG zaC#@c#Dw?DT8$Peo@&CPv61c#WD=gCK~^&=Fib5W4>9HYTy!wQr@&C~)5(LVQ-*8N zL)pchH>)>Y^9fCF@r%9~+;XFQnk%?TYK(f43%+l$88^ zH$OiQH{f(dNl6Jdfz^WpH95JEk5nLKE(C`vX3T00oT5m`$S*$^jZ94uQ&CZ|8#S8W zE#RP|H#{u>EjKq zEsUY)_+E{*R>XK{qCGeFZE>?)gD!`@%VYnj1QuS13VIn*jkR_M{49;X-=^Gaj~#D= z?)TLEVwmL{t&ffEv_0^g$;9@b7~_cfC4}-EU2CMKttu`&mewF1cz?Ccq=`nKh5riu z;IYLV^)BhlB@@W+F7KHJ?V~p@bR&q9a4`RAU$q_VdR`g5zH&5_caTmk&~Kw+y;0*! z8+z>H;_A8y>$|BQE>Tee;o&mWLXFFN-t(>Q?kel(B%fKp>t#YXn3>xb7Z*LGA!B1l z-<*(9QDI53P=HnQnD^qIdWZ(1;*|Y3|NSww0Pps)rQ$WpGc6abbgh8Mi_+2$DJ{1b z>qiEU7%z8}OSO5hqT4gU`B-^`-;K|MJv`L}ValV3DnyUl!METKe_|nRLZq+C( zi%_xth;5AOc97zM(#*Sovjxt?5!V@MVGJ${(&K2xH&o3qVW&9*XkuGD=WLUxp{K6nYFsJqm;sK z^!@N-sZ$slVAAr6-$D_=2D(<+L)kHT7E53=X+~D#R)n~HxoR^^eLmMwcgklWeRb>> zg9Ey7n_!e^A(R(UbnKckvy}r=e~dtJpqJb`aH=t~sN3BqOINl@f@}Y(A@3I1|Ce;i zs2{=*;^BrdA5dsw1R4aO6;!v4+)>B1jc`MZt9%Wg$mxg|Q+mBOncwwk8>za#^;np> z!@f(s(CSjAU^dp~vi_$FgVhnU03`u?J_j(|MF(C)PqDGFW#m9Qs9Va}Qp#EH1Avh> z0nBa=jK#q3zfSG;4G(t@3`7D(`b3$L@LyFApl>^zZoP<-qXTh&YhA=9^z`&dcsVsS zi9dh-wCVm;XJ>+dhljiL!j&= z{RlY~HJ;%5mr8d3OY%SD3cvVsg9T%LiE<%*Y`Nx2WKGJfBfLcR0q0wy6|d(qo|4NT z9qpCwc&ssPwi#MLoIAZgCv_KBV)Boe2@BplS%Gwfp3bU13S>3I1Tdo~9L2RBbo*bAW-3lqtF;e3q{9v+^TpAX{-bD4EN z+T8{C`R2>rKPe8*&UxUpbv~H?qLx9naM<=4!n*`4H@@=E-yXGb#1_JDdN+;>XoAAm zP=@*sD>?3QO!prvyPCxmHy)(_udwd`=kkC5)m{=QN+P3-%F514BqI`{BwIFRWUC}A zyJ0J2k3`6flFRrZtB=p;^E}V{{l4$l{kmWGeWz?K zyGE1i^mhMX_ryo()4$g=&CYb~@NLk@)P5oJ$z_9%WdE(sn{@l9tG(H}9uK~0L7>-_ zc5)_F>%GGFJ2Ev!O@W=q)kbsvst_TbFnnX~x#o*!&zR5N%neFTPChoF$(dDhgW0V`i2KnY)69_Lv96e~ zncO7Gc;eWkd)Cgas_gpw;Rc$KNm3Gd3z5#B))#k*oQN}dx9)RnGgH9WD94;`Ie7Qi zqm!0;{F>L#{^;C1Oc8WEgQZhgvWwduu)%gThTH~4T=Te+})xo8XJj8P$En$%h^96lU)F_Nt@%?1zK{pPn-|ob7Q{@uEIuNEwrN zEGLo4;LrEbC#U&jKmGjK961t3?%XXp+af z{w1Y(RTQ=R0eA8iZSnmPbGtv0E`_&L%h#|7h(%sX(34cUyt!LbMq`q-HgbU47zX#u&3ySZOUT1Gs zxP4i~HTTA=9f&ELb);Jzfc#KDW-GMWvtSiTz1UYu zFO!{J(AJp2YG^C0<#BU%!)d#IbU* z`+GUglI%X?&0zBBZdA*`>AEWkQ|;&aH|=Q$3-leV_h_Hk#@Xy~z9~WT6UWswNhwx3 zzAYO$!9m?=+=m*zoNt^VE!9jYbbG0#`CHrNLHas(7|%PB%X6mk`p2r&==r{G)h2g( zvdCX60s&xOG{V{zxB-B(@QQTJu(V}4T!`3pUaz_y~xV(&KkuFS@@L}}RsNnB(c z;&l<`eQ)Q$e^NqGLXesERlfo0&715b%M7MF*CW22*ypnSi#?5*Yi2IL);y_Ms3NUm z>3co{tLFr(qt{GOj5RVJ>;~H(N~|W1k4oL${PI9x>icRcD3`C3wKW}o674UtxN9_L ziS04&ecX~cZldB6Hmj^@+-z7ke}MdQ&vE&4`lLIA-;2a#EagrywY@)ED$Tu=5PLD= zQV8`?U*3I8-HZHknmteMEao}b&Bi~^@OXc23q|Re`2tA^XD0JveV{ip^#!H)hW$k! zckRE}VttuBw?O08xq}y4g1TCng!x|UQY~qm@;|seqh?#pMsdxl%WY=yon~L_f><%G{^1mtBT+SzhlghT7P@1hcU-{`va7WBV1Nk4@CfFbmy?M%E zZY*=}TEsVz*R`I@KhlU56PmT@1or77RmO1>U(b+goBK!&DQsSqz{MwC&l&rZ@jjK z_(t2fmAOxsWJ*fzb^YY@0(Hx1#iV$|7YPXoK~YiZPSa*S-a*mP{>Yj+xr#aQtZ2qbqH6W>iEbbEw)SFO+3>&nGG+$9FP3Llk6mac!^Kp@FJC6hJ*6w zgc_NnK)vb%eIVF_p1o8ZV{g@?s-dEq04ud;P)~EEnTj6<4f~h=%Z=7b}(Kw$XE)0Yim0k9~3)_|Ka%=eJ z^5wcK>EDlx=-;KMr2GV_(AUOB7G~zhTej`|H8F8}c;h9fwh=1M3=9pMl9icO7ALhc zKEKY-7wGBf2~$WkbyoVjGGf@cPM_;mAUZSU9CgFyY4iSG<#$%-n=|&=eS=hQz^iZW z$7P3C^q=L+cK(XGNvD+3$m`!0UqrEJyZ!8yL9Qn$DSNlj-l8o?wo)t@rrm0=BNcem zmwn32n|4FM(eyw>%jI`^VtPTmoMvd=9(lVCjJ>4Q$XPeEA{2lO69FW2^LxxhL)UhWTQ`PJt}r~Pov;2 znj@M7aDK|mh3|-aE!#SgOmn_!O?1{X{BrE(C{vY6K(F8fYe#VA@HZX|6cFjJkGASWJRZ!)(tbJq{;}$>-{dK?x_H^`N4@)~dh=Zke{XoUcQ5*tXzxDJ(b2(2(-LdQ zA8EKUH++za>QqxxQ^?DgEZQ#9o`QmcU$MxUA2y*;sqE^~gqro#^71k<#Sqvr81#wi za8!7B_*N7z-?kHwQMRmple2u!{L8&+8lIaRAEYlcTt4_P#J<#Wb2E+gd-)kgZs!n- z=-q3q?x(RadoT0NnCG3CktnC7OEAZkqNz4ltKa?os-x|a z|B13n`kAW2wmEq>`c>7|r>(p^{QbnrHQvT7_ZSg3`+M8J}kfNPM2Cx9_Nyg*GsOdAg4)*oumq9-AmTwZ)as#_g$ z5;?FxPX^CK9@ef8$Z9=YPBF2)jN3PTOgX`|n5^9<^6PX!!WDUVsB4=h5)Oe9nqJCC zmhC)S@mtV1g8YYe{U_zb!m@n6;3w|~t~xmhLr@SmKh^eFfGn$Rk>ku+gH@mLU%Ry` z3du)~%lV}AKdCaLzLUdZcwjT@^JaXubD#LS%-q7hE}@s!0TaR9!*tEjdivu^iMDKu z2g_*JcUWm#UAlk7zuY|e#UD^C9&2lB?BkkxXLN^~-dx=q*fY)A!_gB~_kQ!IiN#>w z&GzKPnY-skZi?;v$^F1yY@C(n(03=&g^f{RHnhlKVDfDp<**Pf~QGWLM zTwt@#nWtE&XzP@#67Bv(L_mQ0?N95X5HGJ?pxb&Y$tgevW_9*(?{rp9UVh6GLh!rR$=ceJZ{EBi+Pk9(QGU<+{Ui7P+ts$5KW}Y1 zXKbtYrP!qQ%JF~KdW3W*G9Wr!s^8%BZr7iHR||b4RnC?RsWnW{ZCcE^b6v z&A(7Fzd?uVTftrZ9@j;!Q;Jc>-D1|iByQ#!Uw{VGbG_c^T=e<-Mnm6T6SeMb;|Q*q zIWWhPVZHqte`Qu~?jf0~6~2k=%h36 z>H6-sq@vKF2x_~p^Wk4`i`M;LDcn|uS?JuBezQmCj5WC5P;zsqpgo zo%SVumiR3vdUf-Q;Q#y!@%L>BdtIan>+9eLVU6=*Zl zFWcPQY;A4*3iUa2lfCpv>}h&kPl^_C3^{(@{#&-bjMMyx;i&b0F5#J6@|~&CWXNI8 zVeRm#RaoGmwv0%^zd~NtIGR;vsWsbSz@y6_87^Q&C+fVAd)GEE6iEU1y}SI zpdiL&MpkTfEXPzcNiF3zH#hfKM~>Ipnv0~Q3wdEidYHAA5RoQ|99#EN6a>PHA10B%)>cysa_ zDJcl24F**+f7n(SRJ`%`)aQ1FRL%`u+4@z2_xg7O8#y>SHhr+UV_7twm$s0dRID|O zg^$8=RaD?9NFEWiK4EET+18#GZ?SOqBu&`doGp>4>I)Qa`1!$Rv|AzA{RK|O0ns^f zs0Imey|m;&JXd5!syNHmnsxjF1I1RnKY1Ok9d40!eNqI2>_w~J2UVqp_VYyt1S#mgKhI!$#f1WF)GExu%G%HGh> z&_6J656M$pmxX{pmegbD+}>hb!_3Ugj}JC1W^L&ySARhu7LuZpbnWI%-`iO%oScDS zVMhpR_1GmheS9SVv>)O>(w*A^0s>%ki6$x2@Zj|;CGSz9fQ)89d^}S`qVm!VUtl=@LtbO%qg@&WLO2kvp}la!9!;wifbr-!Prif#=blLR~i9(EG^zJafl+>cjO9OADi)RHUdFw)WJ`XWk9E$GG zutgr_50G)eL$8YwJ+^C?*N9mpt6c+nCv)QDzQhCFLcEwqmeR0_&i^NQc~y~?%D9*v z9u!3GxY&LFwE1XHNzodpXp3*{f1Th3cLbq#N|*36VUxZu{>>@q4jCBu5>jlJw5Xy^Zw!WMvkKy`GkEUa6i!e%*tq%UubA3QcQl{ zmrYDk2n{`t?a)aMyiuCy_PUiXL9)zy9c{BlN%iScY)x{qwfeklL>^QRKEKt7Z# z%xBIh5TZ7U?8)NiFJ8z&B49W-)D!~l7w3BhA0l4?&yAIDkmog zJ4Y5BGK==E@|iSCp%=M!*Y9-`7>=!9Gqs9v>oA#Hzk=gUUquw{1N`bas&k;ZrR8%| zlXB_$f~L^@iCZPc?U==rfG2wIcg2q3_N>_VAM@Lbv6SILHi_GJ?W)CwW;=a7{p|*a z?+>dYsWYB`rhb1SB&yG$u&oI>Dc_HM6`GL1JSsLnJZtdn)de1ye2VPNV$qqeOvGZ3 z@_Uq@C~=w(0TS@`b{#x>{=6nh2NENmBp&#M)#!)dzy)o{_S-wSAs#2e`97TI z?BJlGt-`)Cp5N<$*TQ)W_cAarz<(;Tac~Tv8A1I0$(}X_SErI5;h#z=ny^Qg<>dYZ zoS%4WNlAf)D2KPOIMR`EE?hy~!q3ky9{C(Vi5vMoyWw#2YVF-{>_DJU($NKYTdytM zMg9+mBxjXnaC07Ed z0xUP?eTQl5$f_Kdym)c6eh`O>6itN&upZmSRu`39c!5B_qDrS6{$S7Ey?-h^_Z1Wt z@&IOiEG^qbOG`U7H)jA}*7o5$$E|{o=;+3F_H0I59&#*HQNnh<^zLif71R~<{!m!% z*hfWv>{u<#0#=Ux#*G^!Qqt0dcink_?v^G)my}v&3zp;7>yO$Pdrfq21>PP+ACz=| zuF-^d)k3gJr_DLp*;Bdhdg*0D1r_7I;Rt_Qh5R}}Z`h3e;HElzvl1GqI(!?6cVJ)@ zq%0e&ljj^~42m2xix>)e_Lss`X+BmRm#P$g*!6t;5QT^+wCtA#KrSo|if6$bwo!j2dWa3HuA`7|x-Vqyq#j zs0-tEf%b(cgq|OmHGmQp#*N4L+liu0+9qCqpeRam@{a(aUa_(C03x>IozFjhlprZ; zhy-Co3?x-nR))*`)7ST@I+P{DF|Fa>T0A`_5YQAaqkW&AnwlD}f2gPAJbdSt8o&3j zcgRu`y*1RcoEuY}qHE6F%=Jb_KK4eAky_aFdxn|m>2hEXobaYHclXf+NUobw)lPTq zxV~$=w=9coG?TjPcs*X!u`L@n&UZ?T;@KT3r~|uX)BcH`*SEtGJP0R9L9T zOLKZGtz{T}8Q%GcGC5uLKD!BV9A;7#Pk%Xvo7tVy zp&%)_6;fHG+WRIat@6jsy7DsS%TSW#h?4-B8XI~yQU3n@+rEqAtqaG(XnSL)es`KW z=P8A-k1$`=Xfdh6DW(L6ppj>ORR7D<@{W$96xpMVaN|A2j{W`pZ!yF?g5N?8CkQcF zKP-fP`J)~7vH9>XzyALH45WwCXgk{GkHUj{OH;p1Eh51aKJ@Uo`22+c+FenzuPMPD zOTb-(i@S?yK|9y}SyXjh_&F*m4XO`{E&bYNR2NqMBU|5$p|B8|RK!@i1e*h`mJ;Hk zU1YR6IEv{S*>OFa6RO_~D(*U$($TOp;0_F<>rMGu&^ApGJkJSV-)<+7+WVPE2)E&ib?$zjYT$wW|TBc(? zJ%KB(g<;6(b%b!?=uw|0V}zsuIEf@LdivncZsuEB)V@ta2OPxY)_3pz>jj48ae?zE zDvj;CIXucg!r%QUxXW}ZbPojsWKnT(jHN3hr-{2Rvh1aIbZ`iYjkRho3&eL&P~82_ zlu1C>lP|{C2?&MI6eSVZtsRJ4lBibD{-QS4ajc$Pv*klM0!qIUJx3Aj} zCDeYrN4xh*IM0swrmv`m4dXMTLPAsrQThBvQ$Qp)0v@;ZdG)pRbpp<$mkEH#%p=QC zgifxYs7O=X>t}a24CQ;W!zv?GyP%laf9wnV;AI7c1h@&UBKzz+jWNRO#ed(2)f>U= zv9Yp}oDr~DiK`&lh!dW8p62OK(VHfxV)>fn{ojkZ186QCn z-Jg1_)1ou?H56iJG~PZyG(yNP5Gw-~V}EqA&K#qpAXIUvP zVphno8enJO18G95D?j^D6Z7tg@cDt3dkje%1vC74>f1}jC4(7I0TNyN0O#tA&dJKk z66}yL&G(*Ja&np)<+^|WJ|Vsub&B@&1jPPR z=>rB7(Ud`VPmrJU1B?yKMznA}UE{*FYX=v9+8k&UnSEL)Wb29ZXoEI6!Oxzl>K@F( zgE@A|ke*Pk;P!pJlPMVNo+g?og!6b3^&RM*0UJ(qmIYgyU3AO^;pCZH1>aU2H=x(h zU}1K`KoDYogt92*k=gu2lP6;0i#(Vv3)w#?OsV!58U1ky71joiI;l1II zG)BAUwVLyvbDA@bijJ;sY|QV`Y322Yms1ZrZ}_){sH!FND3^#8b9ER9zcVs-g^z*( zE*F|e9v&VX>{r;XPw7MpB`@e&ji)~Ko&xDXNk#P~K2XfG+tO;Bl0s}{hzT*5q@p5O zX=$nLa5J&^Y7Q>-J)L%Mzz@yh$XP?UiY-!;tQh>Vm54*!1jn z0;2)yOaZ+88XtH4KDrQg~Z{d|3xDCUOSMyRa<#1%KI&VAe`#G?`BYQ-9dQ9?=43#NhA3ey~w74%hrY$ z0fdMdg_sj0xA?(jnFmMmiw@V?@NCCTbV)$tkk1A@9m0pCQ(h8RH~$elio;Ab%Lj+) zIJ+*i2XI^&PV({hmzFX=68(?z;$*BqWqcSIf>^gKa7f_x%;n_d*hSj`R*s6hiGbgA zUvbI14q0%q<1G9`e8xrGf-G)9ZxFMKutVM;Sy~r;o*GUbjDbp`f-Yq7gq1LkFdF3| zp30lspmaai){ZKbcy*W$d{@^t1h&||efupN`YSEg_wGry zajhh~Gd4$JcH-am@#u!l&oQ1|O!E6NUHV%(Z#H$c0y>1!ay>DN< zcA1-?pvJ~neQm8i3crDa8on&TEhqJr=yr=wE@PatIdiv$5m z>fBG5@-^&DfC|DR<50^246}D{qBLp@jcEb0)qj9KZU75YT~osdwHOOaQd&TLb+s-G z?yXXnqo96?<4vgQvXGs?x=I3$6@sp2Oisl)^z$Z^+Q^JHq7oKpd61Z(1?+T) znmUK*IC{I-J2aFM?sg8=vSL{&Mno1Q72-oYyKhNK^pK@(sZI7kJacd2rw}OO>6w{0 z&3sEKDJc>z*f&rGb-)qBsK_+!Mluv0#_l7>mdwGP(*|rRvQ8_Vx@taw>^Mq!DI|~>y0%> z8a`7g2?-L+ks=_*bE+k3&fA0p4`iYa#Ol2M@6Fn05Ll4Y&^Xm=xNj`qsrd8>;mtcs zPBymRn6zdD{0Z&q@4h~dz(6I>o>icc4fMyo_os3Xbb2tSxH5u{hFEyZ5-5sgL=HZH zbO#YseE7!Xn3-F=({P6BVq*x?3d2G4dIq;P6D@TvmX z>OFvmUL*%;XiP`15@-HR8v=1`tp`X(d3#@$mGyCfWkPtsBqSun$aoJ=YYWjICkPf> z?!twK#S5KgpfVVdi-o|00MUO&M^B@W@g+b|N1jC_7*QX9^m!3Lp(P(nx&3|XL%!_+HpZ|wiCa1;r!D~yaG&!3+}MaB$TiClJaD#U54CfF_LEobo6 z-rn9##)l-}PgzmV{W2uvAmkmPz)`Zs#>vRk+>nyO6Z=~)(EIG$x2y0S)bUNMuxo_) z{u074P#quv;9fb1fEAeQD8G3aDGl#syi58Y19Y$dYw%tRckDz%V0U-^zrJy651n>u zE06g6{CNvo;qzPFPpBt01S^|I_Akk2`aIEu@FCBh9lD-*s~RrV+SZn+2Z1NQ{^R~k ze>Kj@FBli7B0(yg;@}{Apq6(1UtjL8U&Ic z3XC8n>Yq`p;g5~A>i`||*|Yxm$Izglj~Jr+1WFU63W`@o(%M~~Y@$2wD{L?%)es() z!{bfQ&!1#t^GQx-1$|2dZ+rIap%r(F0(v77KL{?D5N7%K`sz*gl;99$>wVq}B^Sat zP!ZV}4oOBYra{L$?7?a?TkZbQN*?q4WntGSUwNj#y#|bg9nE$jK(lcs^k_Dhl z|MdIcc4k;Y3ulcICq5W6oWaq4+u`Bi!wdV!$nrMw)6!1se7J!^%QtVhp{O1mWt6Oa zarSidAr4ecJbJX1j8^a?5#V%1M@1nAAn_)9#8$Y@$i~wGO@RpAuHD4x&sA01-r|x+ z`Acp$qS_kaCLvf`{MG5$z&2 zHx|p5K`G;*>Ov+$bVGw}e&@10W2V>;PguzLD;F+o*+d_MB?#&oFem&XOdT5=8xE$H z+GXwGns($GYirXaC*LKSw2xb~4ciXQJ0&WFSKw|CJ{U(l0dSnCTh!Inh0<8{#{g>I#yq6bjM zpzP(#1rysJ`^NpGvFlP$9{Y*yx-_c2S%Wf(ui6_k)FeQ9j>xNb_-F*HwFXi441I&&;y*JSl5N4uxK#bM5qo3lj(dM@Z_}@ogRJ; zDxTw^)sK;6!1O@4@M9&nl>jA-i8P_x3LA_cj+ZV^ID!Ete*T5c{QKez%6VqARb>aV z7~bgLJaUm)I_Tl`ptvjK8h$jVud-Qp#J$pCroLFj!xUuN5~o&l#+W|iW`QjQ14Wbj zakE2-Jc&{)UQtm(e%6YAYJXebZah6XwSI=)VW5=GXuhv>Vsz&(90cqt&&0%2V3lO< z++ks2Vv=veAcGtH;o8mGgJh+12L#TYyQrc)yz?KyHoP4^KELr*>%q z0{kOAuqpB)bSwvbxXz!K=Z`$wc5M5WI}K5~4h~^3b=e@DYHDi{h%iLfH+Oc*3DTlL zy3Oi>1-fHkvH@u8)YQ}$x!*b6W+(Zg1@Arr+G*4I_6lw3TL`fVz35}gtXvwHQ4FNf&q^53l^IQ+47rzH?6HT@*+u892Uw(}HxR!Frd2!+m zdd~=0^?d8<+9z=;^fj8LqlV<*_AQ!u=DK*+E=yAnr5G>pN8;x)3npUscuGDE44hq> z))y8QexR-8KyXHSdXEfvs@pO&h1@qpKHLJhA*-pWfkgcTjem$@($Qnb`jBaAZEdv% zi1{-X{keM@z=U%97PK2ex~H(H$WOiHih{zKG%LW}-2D7dWN{WJj;pAs5KVIYFA>54 zlKJ_045SIV%!AX>Q7VKAr}H{tRa=^y-*vuOZ;ugoZ}|1=M2aei#Jv%b zkwVZiyh~XQk@MT49fCI|9Q?)SNc@5MImtHS(wJpWetf`5{Que>u3z%ROR8H*m;S#$ uQuClaP3tkU?B=e>hZWd^xJd!FwS6@vPr`0o8|omzFIj0tsZ2?oNB;xYL+0lI literal 0 HcmV?d00001 diff --git a/python/examples/antenna-radiation.py b/python/examples/antenna-radiation.py index 12ccfc6bb..9d6ea4cb1 100644 --- a/python/examples/antenna-radiation.py +++ b/python/examples/antenna-radiation.py @@ -1,10 +1,9 @@ -from __future__ import division - import meep as mp import math import numpy as np import matplotlib.pyplot as plt + resolution = 50 # pixels/um sxy = 4 @@ -37,29 +36,57 @@ boundary_layers=pml_layers) nearfield_box = sim.add_near2far(fcen, 0, 1, - mp.Near2FarRegion(center=mp.Vector3(0,+0.5*sxy), size=mp.Vector3(sxy,0), weight=+1), - mp.Near2FarRegion(center=mp.Vector3(0,-0.5*sxy), size=mp.Vector3(sxy,0), weight=-1), - mp.Near2FarRegion(center=mp.Vector3(+0.5*sxy,0), size=mp.Vector3(0,sxy), weight=+1), - mp.Near2FarRegion(center=mp.Vector3(-0.5*sxy,0), size=mp.Vector3(0,sxy), weight=-1)) + mp.Near2FarRegion(center=mp.Vector3(0,+0.5*sxy), + size=mp.Vector3(sxy,0)), + mp.Near2FarRegion(center=mp.Vector3(0,-0.5*sxy), + size=mp.Vector3(sxy,0), + weight=-1), + mp.Near2FarRegion(center=mp.Vector3(+0.5*sxy,0), + size=mp.Vector3(0,sxy)), + mp.Near2FarRegion(center=mp.Vector3(-0.5*sxy,0), + size=mp.Vector3(0,sxy), + weight=-1)) flux_box = sim.add_flux(fcen, 0, 1, - mp.FluxRegion(center=mp.Vector3(0,+0.5*sxy), size=mp.Vector3(sxy,0), weight=+1), - mp.FluxRegion(center=mp.Vector3(0,-0.5*sxy), size=mp.Vector3(sxy,0), weight=-1), - mp.FluxRegion(center=mp.Vector3(+0.5*sxy,0), size=mp.Vector3(0,sxy), weight=+1), - mp.FluxRegion(center=mp.Vector3(-0.5*sxy,0), size=mp.Vector3(0,sxy), weight=-1)) - -sim.run(until_after_sources=mp.stop_when_fields_decayed(50, src_cmpt, mp.Vector3(), 1e-8)) + mp.FluxRegion(center=mp.Vector3(0,+0.5*sxy), + size=mp.Vector3(sxy,0)), + mp.FluxRegion(center=mp.Vector3(0,-0.5*sxy), + size=mp.Vector3(sxy,0), + weight=-1), + mp.FluxRegion(center=mp.Vector3(+0.5*sxy,0), + size=mp.Vector3(0,sxy)), + mp.FluxRegion(center=mp.Vector3(-0.5*sxy,0), + size=mp.Vector3(0,sxy), + weight=-1)) + +sim.run(until_after_sources=mp.stop_when_dft_decayed()) near_flux = mp.get_fluxes(flux_box)[0] -r = 1000/fcen # half side length of far-field square box OR radius of far-field circle -res_ff = 1 # resolution of far fields (points/μm) -far_flux_box = (nearfield_box.flux(mp.Y, mp.Volume(center=mp.Vector3(y=r), size=mp.Vector3(2*r)), res_ff)[0] - - nearfield_box.flux(mp.Y, mp.Volume(center=mp.Vector3(y=-r), size=mp.Vector3(2*r)), res_ff)[0] - + nearfield_box.flux(mp.X, mp.Volume(center=mp.Vector3(r), size=mp.Vector3(y=2*r)), res_ff)[0] - - nearfield_box.flux(mp.X, mp.Volume(center=mp.Vector3(-r), size=mp.Vector3(y=2*r)), res_ff)[0]) - -npts = 100 # number of points in [0,2*pi) range of angles +# half side length of far-field square box OR radius of far-field circle +r = 1000/fcen + +# resolution of far fields (points/μm) +res_ff = 1 + +far_flux_box = (nearfield_box.flux(mp.Y, + mp.Volume(center=mp.Vector3(y=r), + size=mp.Vector3(2*r)), + res_ff)[0] - + nearfield_box.flux(mp.Y, + mp.Volume(center=mp.Vector3(y=-r), + size=mp.Vector3(2*r)), + res_ff)[0] + + nearfield_box.flux(mp.X, + mp.Volume(center=mp.Vector3(r), + size=mp.Vector3(y=2*r)), + res_ff)[0] - + nearfield_box.flux(mp.X, + mp.Volume(center=mp.Vector3(-r), + size=mp.Vector3(y=2*r)), + res_ff)[0]) + +npts = 100 # number of points in [0,2*pi) range of angles angles = 2*math.pi/npts*np.arange(npts) E = np.zeros((npts,3),dtype=np.complex128) @@ -75,6 +102,7 @@ Py = np.real(E[:,2]*H[:,0]-E[:,0]*H[:,2]) Pr = np.sqrt(np.square(Px)+np.square(Py)) +# integrate the radial flux over the circle circumference far_flux_circle = np.sum(Pr)*2*np.pi*r/len(Pr) print("flux:, {:.6f}, {:.6f}, {:.6f}".format(near_flux,far_flux_box,far_flux_circle)) diff --git a/python/examples/antenna_pec_ground_plane.py b/python/examples/antenna_pec_ground_plane.py new file mode 100644 index 000000000..6b65db7ad --- /dev/null +++ b/python/examples/antenna_pec_ground_plane.py @@ -0,0 +1,183 @@ +# Computes the radiation pattern of a dipole antenna +# positioned a given height above a perfect-electric +# conductor (PEC) ground plane and compares the result +# to analytic theory. + +import meep as mp +import math +import numpy as np +import matplotlib +matplotlib.use('agg') +import matplotlib.pyplot as plt + + +resolution = 200 # pixels/um +n = 1.2 # refractive index of surrounding medium +h = 1.25 # height of antenna (point dipole source) above ground plane +wvl = 0.65 # vacuum wavelength +r = 1000*wvl # radius of far-field circle +npts = 50 # number of points in [0,pi/2) range of angles + +angles = 0.5*math.pi/npts*np.arange(npts) + + +def radial_flux(sim,nearfield_box,r): + E = np.zeros((npts,3),dtype=np.complex128) + H = np.zeros((npts,3),dtype=np.complex128) + + for n in range(npts): + ff = sim.get_farfield(nearfield_box, + mp.Vector3(r*math.sin(angles[n]), + r*math.cos(angles[n]))) + E[n,:] = [np.conj(ff[j]) for j in range(3)] + H[n,:] = [ff[j+3] for j in range(3)] + + Px = np.real(E[:,1]*H[:,2]-E[:,2]*H[:,1]) # Ey*Hz-Ez*Hy + Py = np.real(E[:,2]*H[:,0]-E[:,0]*H[:,2]) # Ez*Hx-Ex*Hz + Pr = np.sqrt(np.square(Px)+np.square(Py)) + + return Pr + + +def free_space_radiation(src_cmpt): + sxy = 4 + dpml = 1 + cell_size = mp.Vector3(sxy+2*dpml,sxy+2*dpml) + pml_layers = [mp.PML(dpml)] + + fcen = 1/wvl + sources = [mp.Source(src=mp.GaussianSource(fcen,fwidth=0.2*fcen), + center=mp.Vector3(), + component=src_cmpt)] + + if src_cmpt == mp.Hz: + symmetries = [mp.Mirror(mp.X,phase=-1), + mp.Mirror(mp.Y,phase=-1)] + elif src_cmpt == mp.Ez: + symmetries = [mp.Mirror(mp.X,phase=+1), + mp.Mirror(mp.Y,phase=+1)] + else: + symmetries = [] + + sim = mp.Simulation(cell_size=cell_size, + resolution=resolution, + sources=sources, + symmetries=symmetries, + boundary_layers=pml_layers, + default_material=mp.Medium(index=n)) + + nearfield_box = sim.add_near2far(fcen, + 0, + 1, + mp.Near2FarRegion(center=mp.Vector3(0,+0.5*sxy), + size=mp.Vector3(sxy,0)), + mp.Near2FarRegion(center=mp.Vector3(0,-0.5*sxy), + size=mp.Vector3(sxy,0), + weight=-1), + mp.Near2FarRegion(center=mp.Vector3(+0.5*sxy,0), + size=mp.Vector3(0,sxy)), + mp.Near2FarRegion(center=mp.Vector3(-0.5*sxy,0), + size=mp.Vector3(0,sxy), + weight=-1)) + + sim.run(until_after_sources=mp.stop_when_dft_decayed()) + + Pr = radial_flux(sim,nearfield_box,r) + + return Pr + + +def pec_ground_plane_radiation(src_cmpt=mp.Hz): + L = 8.0 # length of non-PML region + dpml = 1.0 # thickness of PML + sxy = dpml+L+dpml + cell_size = mp.Vector3(sxy,sxy,0) + boundary_layers = [mp.PML(dpml)] + + fcen = 1/wvl + + # The near-to-far field transformation feature only supports + # homogeneous media which means it cannot explicitly take into + # account the ground plane. As a workaround, we use two antennas + # of opposite sign surrounded by a single near2far box which + # encloses both antennas. We then use an odd mirror symmetry to + # divide the computational cell in half which is effectively + # equivalent to a PEC boundary condition on one side. + # Note: This setup means that the radiation pattern can only + # be measured in the top half above the dipole. + sources = [mp.Source(src=mp.GaussianSource(fcen,fwidth=0.2*fcen), + component=src_cmpt, + center=mp.Vector3(0,+h)), + mp.Source(src=mp.GaussianSource(fcen,fwidth=0.2*fcen), + component=src_cmpt, + center=mp.Vector3(0,-h), + amplitude=-1 if src_cmpt==mp.Ez else +1)] + + symmetries = [mp.Mirror(direction=mp.X, + phase=+1 if src_cmpt==mp.Ez else -1), + mp.Mirror(direction=mp.Y, + phase=-1 if src_cmpt==mp.Ez else +1)] + + sim = mp.Simulation(resolution=resolution, + cell_size=cell_size, + boundary_layers=boundary_layers, + sources=sources, + symmetries=symmetries, + default_material=mp.Medium(index=n)) + + nearfield_box = sim.add_near2far(fcen, + 0, + 1, + mp.Near2FarRegion(center=mp.Vector3(0,2*h), + size=mp.Vector3(2*h,0), + weight=+1), + mp.Near2FarRegion(center=mp.Vector3(0,-2*h), + size=mp.Vector3(2*h,0), + weight=-1), + mp.Near2FarRegion(center=mp.Vector3(h,0), + size=mp.Vector3(0,4*h), + weight=+1), + mp.Near2FarRegion(center=mp.Vector3(-h,0), + size=mp.Vector3(0,4*h), + weight=-1)) + + sim.plot2D() + plt.savefig('antenna_pec_ground_plane.png',bbox_inches='tight') + + sim.run(until_after_sources=mp.stop_when_dft_decayed()) + + Pr = radial_flux(sim,nearfield_box,r) + + return Pr + + +if __name__ == '__main__': + src_cmpt = mp.Ez # TM/P: Hz or TE/S: Ez + Pr_fsp = free_space_radiation(src_cmpt) + Pr_pec = pec_ground_plane_radiation(src_cmpt) + + # The radiation pattern of a two-element antenna + # array is equivalent to the radiation pattern of + # a single antenna multiplied by its array factor + # as derived in Section 6.2 "Two-Element Array" of + # Antenna Theory: Analysis and Design, Fourth Edition + # (2016) by C.A. Balanis. + k = 2*np.pi/(wvl/n) # wavevector in free space + Pr_theory = np.zeros(npts,) + for i,ang in enumerate(angles): + Pr_theory[i] = Pr_fsp[i] * 2*np.sin(k*h*np.cos(ang)) + + Pr_pec_norm = Pr_pec/np.max(Pr_pec) + Pr_theory_norm = (Pr_theory/max(Pr_theory))**2 + + plt.figure() + plt.plot(np.degrees(angles),Pr_pec_norm,'b-',label='Meep') + plt.plot(np.degrees(angles),Pr_theory_norm,'r-',label='theory') + plt.xlabel('angle (degrees)') + plt.ylabel('radial flux (normalized by maximum flux)') + plt.title('antenna with {}$_z$ polarization above PEC ground plane'.format('E' if src_cmpt==mp.Ez else r'H')) + plt.axis([0,90,0,1.0]) + plt.legend() + plt.savefig('radiation_pattern.png',bbox_inches='tight') + + print("norm:, {:.6f}".format(np.linalg.norm(Pr_pec_norm-Pr_theory_norm))) diff --git a/python/tests/test_antenna_radiation.py b/python/tests/test_antenna_radiation.py index 7194a1b30..35a8958d8 100644 --- a/python/tests/test_antenna_radiation.py +++ b/python/tests/test_antenna_radiation.py @@ -154,6 +154,11 @@ def test_pec_ground_plane(self): Verifies that the radiation pattern for a point dipole source a given height above a perfect-electric conductor (PEC) ground plane agrees with the theoretical result. + + The radiation pattern of a two-element antenna array is equivalent + to the radiation pattern of a single antenna multiplied by its array + factor as derived in Section 6.2 "Two-Element Array" of Antenna Theory: + Analysis and Design, Fourth Edition (2016) by C.A. Balanis. """ Pr_fsp = self.free_space_radiation() Pr_pec = self.pec_ground_plane_radiation()