From d17b33131c14864bd1eae275f49a3f148e21cf29 Mon Sep 17 00:00:00 2001 From: Leo Chan Date: Thu, 22 Oct 2020 01:53:21 -0400 Subject: Squashed commit of the sb-vbs branch. Includes the SD-VBS benchmarks modified to: - Use libextra to loop as realtime jobs - Preallocate memory before starting their main computation - Accept input via stdin instead of via argc Does not include the SD-VBS matlab code. Fixes libextra execution in LITMUS^RT. --- SD-VBS/common/c/calcSobel_dX.c | 77 + SD-VBS/common/c/calcSobel_dY.c | 79 + SD-VBS/common/c/extra.h | 479 +++ SD-VBS/common/c/fCopy.c | 24 + SD-VBS/common/c/fDeepCopy.c | 24 + SD-VBS/common/c/fDeepCopyRange.c | 24 + SD-VBS/common/c/fDivide.c | 23 + SD-VBS/common/c/fFind3.c | 46 + SD-VBS/common/c/fFreeHandle.c | 16 + SD-VBS/common/c/fHorzcat.c | 40 + SD-VBS/common/c/fMallocHandle.c | 18 + SD-VBS/common/c/fMdivide.c | 27 + SD-VBS/common/c/fMinus.c | 21 + SD-VBS/common/c/fMtimes.c | 38 + SD-VBS/common/c/fPlus.c | 21 + SD-VBS/common/c/fResetArray.c | 19 + SD-VBS/common/c/fResetHandle.c | 19 + SD-VBS/common/c/fReshape.c | 27 + SD-VBS/common/c/fResortIndices.c | 77 + SD-VBS/common/c/fSelfCheck.c | 59 + SD-VBS/common/c/fSetArray.c | 22 + SD-VBS/common/c/fSort.c | 43 + SD-VBS/common/c/fSortIndices.c | 77 + SD-VBS/common/c/fSum.c | 55 + SD-VBS/common/c/fSum2.c | 56 + SD-VBS/common/c/fTimes.c | 21 + SD-VBS/common/c/fTranspose.c | 27 + SD-VBS/common/c/fWriteMatrix.c | 34 + SD-VBS/common/c/ffConv2.c | 47 + SD-VBS/common/c/ffConv2_dY.c | 52 + SD-VBS/common/c/ffDivide.c | 21 + SD-VBS/common/c/ffTimes.c | 21 + SD-VBS/common/c/ffVertcat.c | 36 + SD-VBS/common/c/ffiConv2.c | 54 + SD-VBS/common/c/fiConv2.c | 54 + SD-VBS/common/c/fiCopy.c | 23 + SD-VBS/common/c/fiDeepCopy.c | 23 + SD-VBS/common/c/horzcat.c | 48 + SD-VBS/common/c/iCheck.c | 18 + SD-VBS/common/c/iDeepCopy.c | 23 + SD-VBS/common/c/iDeepCopyRange.c | 23 + SD-VBS/common/c/iFreeHandle.c | 16 + SD-VBS/common/c/iHorzcat.c | 41 + SD-VBS/common/c/iMallocHandle.c | 20 + SD-VBS/common/c/iMinus.c | 21 + SD-VBS/common/c/iResetArray.c | 22 + SD-VBS/common/c/iReshape.c | 25 + SD-VBS/common/c/iSetArray.c | 22 + SD-VBS/common/c/iSort.c | 43 + SD-VBS/common/c/iSortIndices.c | 47 + SD-VBS/common/c/iTimes.c | 22 + SD-VBS/common/c/iTranspose.c | 26 + SD-VBS/common/c/iVertcat.c | 34 + SD-VBS/common/c/ifDeepCopy.c | 25 + SD-VBS/common/c/ifMtimes.c | 38 + SD-VBS/common/c/iiConv2.c | 55 + SD-VBS/common/c/imageBlur.c | 67 + SD-VBS/common/c/imageReblur.c | 67 + SD-VBS/common/c/imageResize.c | 78 + SD-VBS/common/c/isMinus.c | 23 + SD-VBS/common/c/isPlus.c | 22 + SD-VBS/common/c/photonEndTiming.c | 22 + SD-VBS/common/c/photonPrintTiming.c | 22 + SD-VBS/common/c/photonReportTiming.c | 28 + SD-VBS/common/c/photonStartTiming.c | 23 + SD-VBS/common/c/randWrapper.c | 30 + SD-VBS/common/c/randnWrapper.c | 40 + SD-VBS/common/c/readFile.c | 42 + SD-VBS/common/c/readImage.c | 112 + SD-VBS/common/c/sdvbs_common.h | 139 + SD-VBS/common/c/selfCheck.c | 65 + SD-VBS/common/c/timingUtils.h | 99 + SD-VBS/common/c/uiFreeHandle.c | 15 + SD-VBS/common/c/uiMallocHandle.c | 20 + SD-VBS/common/c/uiResetArray.c | 19 + SD-VBS/common/c/uiSetArray.c | 21 + SD-VBS/common/c/writeMatrix.c | 34 + SD-VBS/common/makefiles/Makefile.common | 134 + SD-VBS/common/makefiles/Makefile.include | 16 + SD-VBS/common/makefiles/Makefile.recurse | 41 + SD-VBS/common/support/buildTable.py | 54 + SD-VBS/common/support/buildTimeTable.py | 55 + SD-VBS/common/toolbox/MultiNcut/MNcut.m | 93 + SD-VBS/common/toolbox/MultiNcut/MNcutDemo.m | 34 + SD-VBS/common/toolbox/MultiNcut/README.tex | 9 + SD-VBS/common/toolbox/MultiNcut/a_times_b_cmplx.c | 405 +++ .../common/toolbox/MultiNcut/a_times_b_cmplx.dll | Bin 0 -> 7114 bytes .../toolbox/MultiNcut/a_times_b_cmplx.mexa64 | Bin 0 -> 10646 bytes .../toolbox/MultiNcut/a_times_b_cmplx.mexglx | Bin 0 -> 7896 bytes .../toolbox/MultiNcut/a_times_b_cmplx.mexmac | Bin 0 -> 13096 bytes SD-VBS/common/toolbox/MultiNcut/affinityic.c | 187 ++ SD-VBS/common/toolbox/MultiNcut/affinityic.dll | Bin 0 -> 7680 bytes SD-VBS/common/toolbox/MultiNcut/affinityic.mexa64 | Bin 0 -> 9755 bytes SD-VBS/common/toolbox/MultiNcut/affinityic.mexglx | Bin 0 -> 7775 bytes SD-VBS/common/toolbox/MultiNcut/batch_MNcut.m | 48 + SD-VBS/common/toolbox/MultiNcut/cimgnbmap.c | 198 ++ SD-VBS/common/toolbox/MultiNcut/cimgnbmap.dll | Bin 0 -> 7168 bytes SD-VBS/common/toolbox/MultiNcut/cimgnbmap.mexa64 | Bin 0 -> 9598 bytes SD-VBS/common/toolbox/MultiNcut/cimgnbmap.mexglx | Bin 0 -> 7824 bytes SD-VBS/common/toolbox/MultiNcut/cimgnbmap_cross.c | 197 ++ .../common/toolbox/MultiNcut/cimgnbmap_cross.dll | Bin 0 -> 7168 bytes .../toolbox/MultiNcut/cimgnbmap_cross.mexa64 | Bin 0 -> 9604 bytes .../toolbox/MultiNcut/cimgnbmap_cross.mexglx | Bin 0 -> 7830 bytes SD-VBS/common/toolbox/MultiNcut/cimgnbmap_star.c | 294 ++ SD-VBS/common/toolbox/MultiNcut/cimgnbmap_star.dll | Bin 0 -> 7680 bytes .../common/toolbox/MultiNcut/cimgnbmap_star.mexa64 | Bin 0 -> 9747 bytes .../common/toolbox/MultiNcut/cimgnbmap_star.mexglx | Bin 0 -> 7829 bytes SD-VBS/common/toolbox/MultiNcut/compileAll.m | 10 + SD-VBS/common/toolbox/MultiNcut/computeMultiW.m | 245 ++ SD-VBS/common/toolbox/MultiNcut/discretisation.m | 49 + .../MultiNcut/discretisationEigenVectorData.m | 12 + SD-VBS/common/toolbox/MultiNcut/doog1.m | 32 + SD-VBS/common/toolbox/MultiNcut/doog2.m | 38 + SD-VBS/common/toolbox/MultiNcut/eigSolve.m | 5 + SD-VBS/common/toolbox/MultiNcut/fft_filt_2.m | 29 + SD-VBS/common/toolbox/MultiNcut/gaussian.m | 31 + .../toolbox/MultiNcut/make_filterbank_even2.m | 45 + .../toolbox/MultiNcut/make_filterbank_odd2.m | 46 + .../common/toolbox/MultiNcut/mex_projection_QR.c | 82 + .../common/toolbox/MultiNcut/mex_projection_QR.dll | Bin 0 -> 10240 bytes .../toolbox/MultiNcut/mex_projection_QR.mexa64 | Bin 0 -> 13067 bytes .../toolbox/MultiNcut/mex_projection_QR.mexglx | Bin 0 -> 10165 bytes .../MultiNcut/mex_projection_QR_symmetric.c | 83 + .../MultiNcut/mex_projection_QR_symmetric.dll | Bin 0 -> 10240 bytes .../MultiNcut/mex_projection_QR_symmetric.mexa64 | Bin 0 -> 13093 bytes .../MultiNcut/mex_projection_QR_symmetric.mexglx | Bin 0 -> 10175 bytes .../MultiNcut/mex_w_times_x_symmetric.mexglx | Bin 0 -> 8713 bytes .../MultiNcut/mex_w_times_x_symmetric.mexmac | Bin 0 -> 13396 bytes SD-VBS/common/toolbox/MultiNcut/multiAffinityic.c | 216 ++ .../common/toolbox/MultiNcut/multiAffinityic.dll | Bin 0 -> 8192 bytes .../toolbox/MultiNcut/multiAffinityic.mexa64 | Bin 0 -> 10138 bytes .../toolbox/MultiNcut/multiAffinityic.mexglx | Bin 0 -> 8134 bytes .../toolbox/MultiNcut/multiIntensityFirstLayer.c | 126 + .../toolbox/MultiNcut/multiIntensityFirstLayer.dll | Bin 0 -> 7168 bytes .../MultiNcut/multiIntensityFirstLayer.mexa64 | Bin 0 -> 9345 bytes .../MultiNcut/multiIntensityFirstLayer.mexglx | Bin 0 -> 6805 bytes .../common/toolbox/MultiNcut/multiIntensityWppc.c | 158 + .../toolbox/MultiNcut/multiIntensityWppc.dll | Bin 0 -> 7168 bytes .../toolbox/MultiNcut/multiIntensityWppc.mexa64 | Bin 0 -> 9493 bytes .../toolbox/MultiNcut/multiIntensityWppc.mexglx | Bin 0 -> 7277 bytes SD-VBS/common/toolbox/MultiNcut/quadedgep2.m | 188 ++ .../common/toolbox/MultiNcut/quickNcutHardBiais2.m | 187 ++ SD-VBS/common/toolbox/MultiNcut/read_data.m | 13 + SD-VBS/common/toolbox/MultiNcut/readimage.m | 15 + SD-VBS/common/toolbox/MultiNcut/run_script.m | 60 + SD-VBS/common/toolbox/MultiNcut/showmask.m | 65 + SD-VBS/common/toolbox/MultiNcut/sparsifyc.c | 232 ++ SD-VBS/common/toolbox/MultiNcut/sparsifyc.dll | Bin 0 -> 8704 bytes SD-VBS/common/toolbox/MultiNcut/sparsifyc.mexa64 | Bin 0 -> 10322 bytes SD-VBS/common/toolbox/MultiNcut/sparsifyc.mexglx | Bin 0 -> 8296 bytes SD-VBS/common/toolbox/MultiNcut/sparsifyc.mexmac | Bin 0 -> 9004 bytes SD-VBS/common/toolbox/MultiNcut/spmtimesd.c | 141 + SD-VBS/common/toolbox/MultiNcut/spmtimesd.dll | Bin 0 -> 7168 bytes SD-VBS/common/toolbox/MultiNcut/spmtimesd.mexa64 | Bin 0 -> 9282 bytes SD-VBS/common/toolbox/MultiNcut/spmtimesd.mexglx | Bin 0 -> 7280 bytes SD-VBS/common/toolbox/MultiNcut/spmtimesd.mexmac | Bin 0 -> 8888 bytes SD-VBS/common/toolbox/MultiNcut/tim_eigs.m | 1084 +++++++ SD-VBS/common/toolbox/ikkjin/getANMS.m | 30 + SD-VBS/common/toolbox/ikkjin/getImgGrad.m | 7 + SD-VBS/common/toolbox/ikkjin/harris.m | 43 + SD-VBS/common/toolbox/lagrcv/Makefile | 21 + SD-VBS/common/toolbox/lagrcv/README.sxw | Bin 0 -> 5929 bytes SD-VBS/common/toolbox/lagrcv/calcGradientPyrMex.cc | 45 + .../toolbox/lagrcv/calcGradientPyrMex.mexa64 | Bin 0 -> 28391 bytes .../toolbox/lagrcv/calcGradientPyrMex.mexglx | Bin 0 -> 23141 bytes SD-VBS/common/toolbox/lagrcv/calcImgBlurMex.cc | 30 + SD-VBS/common/toolbox/lagrcv/calcImgBlurMex.mexa64 | Bin 0 -> 27799 bytes SD-VBS/common/toolbox/lagrcv/calcImgBlurMex.mexglx | Bin 0 -> 22665 bytes SD-VBS/common/toolbox/lagrcv/calcOptFlowLKMex.cc | 85 + .../common/toolbox/lagrcv/calcOptFlowLKMex.mexa64 | Bin 0 -> 28499 bytes .../common/toolbox/lagrcv/calcOptFlowLKMex.mexglx | Bin 0 -> 23321 bytes .../common/toolbox/lagrcv/calcOptFlowLKPyrMex.cc | 99 + .../toolbox/lagrcv/calcOptFlowLKPyrMex.mexa64 | Bin 0 -> 28778 bytes .../toolbox/lagrcv/calcOptFlowLKPyrMex.mexglx | Bin 0 -> 23692 bytes .../common/toolbox/lagrcv/calcOptFlowLKPyrMex2.cc | 99 + .../toolbox/lagrcv/calcOptFlowLKPyrMex2.mexa64 | Bin 0 -> 28811 bytes .../toolbox/lagrcv/calcOptFlowLKPyrMex2.mexglx | Bin 0 -> 23725 bytes .../toolbox/lagrcv/calcOptFlowLKPyrWInitMex.cc | 91 + .../toolbox/lagrcv/calcOptFlowLKPyrWInitMex.mexa64 | Bin 0 -> 28815 bytes .../toolbox/lagrcv/calcOptFlowLKPyrWInitMex.mexglx | Bin 0 -> 23693 bytes .../toolbox/lagrcv/calcOptFlowLKPyrWInitMex2.cc | 91 + .../lagrcv/calcOptFlowLKPyrWInitMex2.mexa64 | Bin 0 -> 28880 bytes .../lagrcv/calcOptFlowLKPyrWInitMex2.mexglx | Bin 0 -> 23726 bytes .../lagrcv/calcOptFlowLKPyrWInitSobelMex.cc | 87 + .../lagrcv/calcOptFlowLKPyrWInitSobelMex.mexa64 | Bin 0 -> 28724 bytes .../lagrcv/calcOptFlowLKPyrWInitSobelMex.mexglx | Bin 0 -> 23558 bytes SD-VBS/common/toolbox/lagrcv/calcOpticalFlowLK.cc | 59 + .../common/toolbox/lagrcv/calcOpticalFlowPyrLK.cc | 77 + .../toolbox/lagrcv/calcOpticalFlowPyrLK.mexglx | Bin 0 -> 6538 bytes SD-VBS/common/toolbox/lagrcv/calcResizedImgMex.cc | 33 + .../common/toolbox/lagrcv/calcResizedImgMex.mexa64 | Bin 0 -> 27842 bytes .../common/toolbox/lagrcv/calcResizedImgMex.mexglx | Bin 0 -> 22704 bytes SD-VBS/common/toolbox/lagrcv/calcSobelMex.cc | 32 + SD-VBS/common/toolbox/lagrcv/calcSobelMex.mexa64 | Bin 0 -> 27837 bytes SD-VBS/common/toolbox/lagrcv/calcSobelMex.mexglx | Bin 0 -> 22699 bytes SD-VBS/common/toolbox/lagrcv/calcSobelPyrMex.cc | 44 + .../common/toolbox/lagrcv/calcSobelPyrMex.mexa64 | Bin 0 -> 28388 bytes .../common/toolbox/lagrcv/calcSobelPyrMex.mexglx | Bin 0 -> 23138 bytes .../common/toolbox/lagrcv/calcSubsampleAvgMex.cc | 33 + .../toolbox/lagrcv/calcSubsampleAvgMex.mexa64 | Bin 0 -> 27844 bytes .../toolbox/lagrcv/calcSubsampleAvgMex.mexglx | Bin 0 -> 22706 bytes SD-VBS/common/toolbox/lagrcv/calcTextureMex.cc | 53 + SD-VBS/common/toolbox/lagrcv/calcTextureMex.mexa64 | Bin 0 -> 28273 bytes SD-VBS/common/toolbox/lagrcv/calcTextureMex.mexglx | Bin 0 -> 23171 bytes SD-VBS/common/toolbox/lagrcv/calcTexturePyrMex.cc | 54 + .../common/toolbox/lagrcv/calcTexturePyrMex.mexa64 | Bin 0 -> 28392 bytes .../common/toolbox/lagrcv/calcTexturePyrMex.mexglx | Bin 0 -> 23226 bytes SD-VBS/common/toolbox/lagrcv/dummyMex.cc | 58 + SD-VBS/common/toolbox/lagrcv/dummyMex.mexa64 | Bin 0 -> 8245 bytes SD-VBS/common/toolbox/lagrcv/dummyMex.mexglx | Bin 0 -> 6329 bytes SD-VBS/common/toolbox/lagrcv/findCornerSubPix.cc | 39 + .../common/toolbox/lagrcv/goodFeaturesToTrack.cc | 62 + .../toolbox/lagrcv/goodFeaturesToTrack.mexglx | Bin 0 -> 6280 bytes SD-VBS/common/toolbox/lagrcv/lagrcv.cpp | 840 ++++++ SD-VBS/common/toolbox/lagrcv/lagrcv.h | 51 + SD-VBS/common/toolbox/lagrcv/liblagrcv.a | Bin 0 -> 26268 bytes SD-VBS/common/toolbox/lagrcv/lk_flow.cc | 76 + SD-VBS/common/toolbox/lagrcv/lk_flow.mexglx | Bin 0 -> 7224 bytes SD-VBS/common/toolbox/lagrcv/test.cc | 34 + SD-VBS/common/toolbox/lagrcv/test/getPyramid.m | 10 + SD-VBS/common/toolbox/lagrcv/test/img0.ppm | 3137 ++++++++++++++++++++ SD-VBS/common/toolbox/lagrcv/test/img1.ppm | 3100 +++++++++++++++++++ SD-VBS/common/toolbox/lagrcv/test/pathdef.m | 284 ++ SD-VBS/common/toolbox/lagrcv/test/test_lk.m | 74 + SD-VBS/common/toolbox/lagrcv/test/test_lk_disp.m | 49 + SD-VBS/common/toolbox/lagrcv/test/test_lk_opencv.m | 47 + SD-VBS/common/toolbox/mex_template.c | 58 + .../toolbox_basic/TOOLBOX_calib/Distor2Calib.m | 391 +++ .../toolbox_basic/TOOLBOX_calib/Rectangle2Square.m | 19 + .../toolbox_basic/TOOLBOX_calib/UnWarpPlane.m | 54 + .../toolbox_basic/TOOLBOX_calib/add_suppress.m | 98 + .../toolbox_basic/TOOLBOX_calib/analyse_error.m | 141 + .../toolbox_basic/TOOLBOX_calib/apply_distortion.m | 137 + .../toolbox_basic/TOOLBOX_calib/calib_gui.m | 117 + .../TOOLBOX_calib/check_active_images.m | 19 + .../TOOLBOX_calib/check_convergence.m | 48 + .../toolbox_basic/TOOLBOX_calib/check_directory.m | 97 + .../TOOLBOX_calib/check_extracted_images.m | 37 + .../toolbox_basic/TOOLBOX_calib/clear_windows.m | 4 + .../toolbox/toolbox_basic/TOOLBOX_calib/clearwin.m | 10 + .../toolbox_basic/TOOLBOX_calib/click_calib.m | 193 ++ .../toolbox_basic/TOOLBOX_calib/click_ima_calib.m | 230 ++ .../TOOLBOX_calib/click_ima_calib3D.m | 482 +++ .../toolbox_basic/TOOLBOX_calib/comp_distortion.m | 38 + .../toolbox_basic/TOOLBOX_calib/comp_distortion2.m | 71 + .../TOOLBOX_calib/comp_distortion_oulu.m | 47 + .../toolbox_basic/TOOLBOX_calib/comp_error_calib.m | 46 + .../TOOLBOX_calib/compute_collineation.m | 66 + .../TOOLBOX_calib/compute_extrinsic.m | 123 + .../TOOLBOX_calib/compute_extrinsic_init.m | 151 + .../TOOLBOX_calib/compute_extrinsic_refine.m | 113 + .../TOOLBOX_calib/compute_homography.m | 163 + .../toolbox_basic/TOOLBOX_calib/cornerfinder.m | 215 ++ .../toolbox_basic/TOOLBOX_calib/count_squares.m | 74 + .../toolbox_basic/TOOLBOX_calib/data_calib.m | 92 + .../toolbox_basic/TOOLBOX_calib/error_analysis.m | 182 ++ .../TOOLBOX_calib/export_calib_data.m | 99 + .../toolbox_basic/TOOLBOX_calib/ext_calib.m | 152 + .../toolbox_basic/TOOLBOX_calib/extract_grid.m | 234 ++ .../TOOLBOX_calib/extract_parameters.m | 46 + .../TOOLBOX_calib/extract_parameters3D.m | 36 + .../TOOLBOX_calib/extrinsic_computation.m | 185 ++ .../toolbox_basic/TOOLBOX_calib/fixallvariables.m | 19 + .../toolbox_basic/TOOLBOX_calib/fixvariable.m | 18 + .../toolbox/toolbox_basic/TOOLBOX_calib/ginput3.m | 216 ++ .../toolbox_basic/TOOLBOX_calib/go_calib_optim.m | 139 + .../TOOLBOX_calib/go_calib_optim_iter.m | 394 +++ .../toolbox_basic/TOOLBOX_calib/ima_read_calib.m | 158 + .../TOOLBOX_calib/init_intrinsic_param.m | 158 + .../toolbox/toolbox_basic/TOOLBOX_calib/is3D.m | 19 + .../toolbox_basic/TOOLBOX_calib/loading_calib.m | 10 + .../toolbox/toolbox_basic/TOOLBOX_calib/loadinr.m | 52 + .../toolbox/toolbox_basic/TOOLBOX_calib/loadpgm.m | 89 + .../toolbox/toolbox_basic/TOOLBOX_calib/loadppm.m | 109 + .../toolbox_basic/TOOLBOX_calib/mean_std_robust.m | 7 + .../toolbox/toolbox_basic/TOOLBOX_calib/mosaic.m | 92 + .../toolbox_basic/TOOLBOX_calib/normalize.m | 43 + .../toolbox/toolbox_basic/TOOLBOX_calib/pgmread.m | 26 + .../toolbox_basic/TOOLBOX_calib/project2_oulu.m | 53 + .../toolbox_basic/TOOLBOX_calib/project_points.m | 276 ++ .../toolbox_basic/TOOLBOX_calib/project_points2.m | 312 ++ .../toolbox_basic/TOOLBOX_calib/projectedGrid.m | 24 + .../toolbox_basic/TOOLBOX_calib/projector_calib.m | 258 ++ .../toolbox/toolbox_basic/TOOLBOX_calib/readras.m | 87 + .../TOOLBOX_calib/recomp_corner_calib.m | 119 + .../toolbox/toolbox_basic/TOOLBOX_calib/rect.m | 127 + .../toolbox_basic/TOOLBOX_calib/reproject_calib.m | 121 + .../toolbox_basic/TOOLBOX_calib/rigid_motion.m | 66 + .../toolbox_basic/TOOLBOX_calib/rodrigues.m | 217 ++ .../toolbox/toolbox_basic/TOOLBOX_calib/rotation.m | 23 + .../TOOLBOX_calib/run_error_analysis.m | 65 + .../toolbox/toolbox_basic/TOOLBOX_calib/saveinr.m | 46 + .../toolbox/toolbox_basic/TOOLBOX_calib/savepgm.m | 22 + .../toolbox/toolbox_basic/TOOLBOX_calib/saveppm.m | 45 + .../toolbox_basic/TOOLBOX_calib/saving_calib.m | 95 + .../TOOLBOX_calib/script_fit_distortion.m | 39 + .../toolbox/toolbox_basic/TOOLBOX_calib/startup.m | 9 + .../toolbox_basic/TOOLBOX_calib/undistort_image.m | 193 ++ .../toolbox_basic/TOOLBOX_calib/willson_convert.m | 89 + .../toolbox_basic/TOOLBOX_calib/willson_read.m | 59 + .../toolbox/toolbox_basic/TOOLBOX_calib/writeras.m | 105 + SD-VBS/common/toolbox/toolbox_basic/affine/README | 5 + .../common/toolbox/toolbox_basic/affine/carve_it.m | 25 + .../toolbox/toolbox_basic/affine/compute_AD.m | 90 + .../toolbox/toolbox_basic/affine/compute_AD_disp.m | 103 + .../toolbox/toolbox_basic/affine/compute_J.m | 31 + .../common/toolbox/toolbox_basic/affine/find_AD.m | 82 + .../common/toolbox/toolbox_basic/affine/find_D.m | 65 + .../toolbox/toolbox_basic/affine/find_center.m | 4 + .../toolbox/toolbox_basic/affine/gen_feature_s.m | 17 + SD-VBS/common/toolbox/toolbox_basic/affine/grad.m | 24 + .../toolbox/toolbox_basic/affine/hemisphere_s.m | 27 + SD-VBS/common/toolbox/toolbox_basic/affine/im.m | 3 + .../common/toolbox/toolbox_basic/affine/iter_AD.m | 26 + .../toolbox/toolbox_basic/affine/m_interp4.m | 49 + .../toolbox/toolbox_basic/affine/norm_inten.m | 11 + .../common/toolbox/toolbox_basic/affine/pan.0.pgm | 53 + .../common/toolbox/toolbox_basic/affine/pan.1.pgm | 59 + .../common/toolbox/toolbox_basic/affine/readpgm.m | 26 + .../toolbox/toolbox_basic/affine/simulation.m | 42 + .../toolbox_basic/affine/sports1_11_28.jpeg | Bin 0 -> 23655 bytes .../toolbox/toolbox_basic/affine/test_affine.m | 33 + SD-VBS/common/toolbox/toolbox_basic/affinityic.c | 186 ++ .../toolbox/toolbox_basic/calib/TOOLBOX_calib.tar | Bin 0 -> 98304 bytes .../toolbox_basic/calib_bouguetj/Distor2Calib.m | 391 +++ .../calib_bouguetj/Multi_Calib_oulu.m | 12 + .../calib_bouguetj/Rectangle2Square.m | 19 + .../toolbox_basic/calib_bouguetj/UnWarpPlane.m | 54 + .../toolbox_basic/calib_bouguetj/add_suppress.m | 91 + .../toolbox_basic/calib_bouguetj/analyse_error.m | 104 + .../toolbox/toolbox_basic/calib_bouguetj/calib.m | 74 + .../toolbox_basic/calib_bouguetj/calib3D_gui.m | 115 + .../toolbox_basic/calib_bouguetj/calib_gui.m | 81 + .../calib_bouguetj/check_active_images.m | 14 + .../calib_bouguetj/check_convergence.m | 17 + .../toolbox_basic/calib_bouguetj/check_planarity.m | 41 + .../toolbox_basic/calib_bouguetj/click_calib.m | 99 + .../toolbox_basic/calib_bouguetj/click_calib3D.m | 79 + .../toolbox_basic/calib_bouguetj/click_ima_calib.m | 218 ++ .../calib_bouguetj/click_ima_calib3D.m | 482 +++ .../toolbox_basic/calib_bouguetj/comp_distortion.m | 38 + .../calib_bouguetj/comp_distortion2.m | 71 + .../calib_bouguetj/comp_distortion_oulu.m | 47 + .../calib_bouguetj/comp_error_calib.m | 40 + .../calib_bouguetj/compute_collineation.m | 66 + .../calib_bouguetj/compute_extrinsic.m | 123 + .../calib_bouguetj/compute_extrinsic_init.m | 149 + .../calib_bouguetj/compute_extrinsic_refine.m | 110 + .../calib_bouguetj/compute_homography.m | 163 + .../toolbox_basic/calib_bouguetj/convert_oulu.m | 35 + .../toolbox_basic/calib_bouguetj/cornerfinder.m | 215 ++ .../toolbox_basic/calib_bouguetj/count_squares.m | 74 + .../toolbox_basic/calib_bouguetj/data_calib.m | 89 + .../toolbox_basic/calib_bouguetj/error_analysis.m | 182 ++ .../toolbox_basic/calib_bouguetj/ext_calib.m | 130 + .../toolbox_basic/calib_bouguetj/extract_grid.m | 227 ++ .../calib_bouguetj/extract_parameters.m | 46 + .../calib_bouguetj/extract_parameters3D.m | 36 + .../calib_bouguetj/extrinsic_computation.m | 173 ++ .../toolbox/toolbox_basic/calib_bouguetj/ginput3.m | 216 ++ .../toolbox_basic/calib_bouguetj/go_calib_optim.m | 60 + .../calib_bouguetj/go_calib_optim3D.m | 264 ++ .../calib_bouguetj/go_calib_optim_cont.m | 142 + .../calib_bouguetj/go_calib_optim_iter.m | 332 +++ .../toolbox_basic/calib_bouguetj/graphout_calib.m | 12 + .../calib_bouguetj/graphout_calib3D.m | 153 + .../toolbox_basic/calib_bouguetj/ima_read_calib.m | 107 + .../calib_bouguetj/init_calib_param.m | 210 ++ .../calib_bouguetj/init_intrinsic_param.m | 153 + .../toolbox/toolbox_basic/calib_bouguetj/is3D.m | 19 + .../toolbox_basic/calib_bouguetj/loading_calib.m | 10 + .../toolbox/toolbox_basic/calib_bouguetj/loadinr.m | 52 + .../toolbox/toolbox_basic/calib_bouguetj/loadpgm.m | 89 + .../toolbox/toolbox_basic/calib_bouguetj/loadppm.m | 101 + .../toolbox_basic/calib_bouguetj/mean_std_robust.m | 7 + .../calib_bouguetj/multi_error_oulu.m | 49 + .../toolbox_basic/calib_bouguetj/normalize.m | 32 + .../toolbox/toolbox_basic/calib_bouguetj/pgmread.m | 26 + .../toolbox_basic/calib_bouguetj/project2_oulu.m | 53 + .../toolbox_basic/calib_bouguetj/project_points.m | 276 ++ .../toolbox_basic/calib_bouguetj/projectedGrid.m | 24 + .../toolbox/toolbox_basic/calib_bouguetj/readras.m | 87 + .../calib_bouguetj/recomp_corner_calib.m | 96 + .../toolbox/toolbox_basic/calib_bouguetj/rect.m | 93 + .../toolbox_basic/calib_bouguetj/reproject_calib.m | 92 + .../toolbox_basic/calib_bouguetj/rigid_motion.m | 66 + .../toolbox_basic/calib_bouguetj/rodrigues.m | 217 ++ .../toolbox_basic/calib_bouguetj/rotation.m | 23 + .../calib_bouguetj/run_error_analysis.m | 65 + .../toolbox/toolbox_basic/calib_bouguetj/saveinr.m | 46 + .../toolbox/toolbox_basic/calib_bouguetj/savepgm.m | 22 + .../toolbox/toolbox_basic/calib_bouguetj/saveppm.m | 25 + .../toolbox_basic/calib_bouguetj/saving_calib.m | 27 + .../calib_bouguetj/script_fit_distortion.m | 39 + .../calib_bouguetj/select_sol_no_center.m | 19 + .../calib_bouguetj/select_sol_no_center3D.m | 20 + .../calib_bouguetj/select_sol_with_center.m | 19 + .../calib_bouguetj/select_sol_with_center3D.m | 20 + .../toolbox/toolbox_basic/calib_bouguetj/startup.m | 9 + .../toolbox/toolbox_basic/calib_bouguetj/test_3d.m | 80 + .../toolbox_basic/calib_bouguetj/undistort_image.m | 88 + .../toolbox_basic/calib_bouguetj/writeras.m | 105 + .../calib_bouguetj2/TOOLBOX_calib.tar | Bin 0 -> 253952 bytes .../common/toolbox/toolbox_basic/common/Ncut_IC.m | 26 + .../toolbox/toolbox_basic/common/Ncut_IC_m.m | 42 + .../toolbox/toolbox_basic/common/Ncut_IC_m2.m | 51 + .../toolbox/toolbox_basic/common/affinityic.c | 186 ++ .../toolbox/toolbox_basic/common/affinityic.mexa64 | Bin 0 -> 10209 bytes .../toolbox/toolbox_basic/common/affinityic.mexglx | Bin 0 -> 8828 bytes .../toolbox/toolbox_basic/common/anisodiff.m | 20 + SD-VBS/common/toolbox/toolbox_basic/common/bin.m | 39 + .../toolbox/toolbox_basic/common/cimgnbmap.c | 189 ++ .../toolbox/toolbox_basic/common/cimgnbmap.mexa64 | Bin 0 -> 9679 bytes .../toolbox/toolbox_basic/common/cimgnbmap.mexglx | Bin 0 -> 8486 bytes .../common/toolbox/toolbox_basic/common/density.m | 133 + .../toolbox/toolbox_basic/common/find_edge.m | 24 + SD-VBS/common/toolbox/toolbox_basic/common/grad.m | 28 + .../toolbox_basic/common/make_filterbank_even2.m | 45 + .../toolbox_basic/common/make_filterbank_odd2.m | 46 + .../toolbox/toolbox_basic/common/max_supress2.m | 59 + SD-VBS/common/toolbox/toolbox_basic/common/mgrad.m | 11 + .../common/toolbox/toolbox_basic/common/mpgread.m | 25 + .../toolbox/toolbox_basic/common/mpgread.mexlx | Bin 0 -> 84735 bytes .../common/toolbox/toolbox_basic/common/mpgwrite.m | 29 + .../toolbox/toolbox_basic/common/mpgwrite.mexlx | Bin 0 -> 105791 bytes SD-VBS/common/toolbox/toolbox_basic/common/ncut.m | 108 + .../common/toolbox/toolbox_basic/common/ncut_b.m | 46 + .../common/toolbox/toolbox_basic/common/ncut_bb.m | 39 + .../common/toolbox/toolbox_basic/common/ncut_e.m | 36 + .../common/toolbox/toolbox_basic/common/ncut_neg.m | 45 + .../toolbox/toolbox_basic/common/ncut_sparse.m | 45 + .../common/toolbox/toolbox_basic/common/ncut_tmp.m | 45 + SD-VBS/common/toolbox/toolbox_basic/common/ncutd.m | 108 + .../toolbox/toolbox_basic/common/nonmaxsup.m | 81 + .../toolbox/toolbox_basic/common/pair_dist.m | 14 + .../toolbox/toolbox_basic/common/quadedgep.m | 106 + .../common/toolbox/toolbox_basic/common/readpcm.m | 12 + .../common/toolbox/toolbox_basic/common/readpdm.m | 8 + .../common/toolbox/toolbox_basic/common/readpfm.m | 10 + .../toolbox/toolbox_basic/common/renormalize.m | 32 + .../toolbox/toolbox_basic/common/show_edge.m | 11 + .../toolbox/toolbox_basic/common/spmtimesd.c | 141 + .../toolbox/toolbox_basic/common/spmtimesd.mexa64 | Bin 0 -> 9427 bytes .../toolbox/toolbox_basic/common/spmtimesd.mexglx | Bin 0 -> 8198 bytes SD-VBS/common/toolbox/toolbox_basic/common/tmp.tex | 16 + .../common/toolbox/toolbox_basic/common/vmquant.m | 112 + .../toolbox/toolbox_basic/common/vmquantc.mexhp7 | Bin 0 -> 24603 bytes .../toolbox/toolbox_basic/common/vmquantc.mexlx | Bin 0 -> 16987 bytes .../toolbox/toolbox_basic/common/vmquantc.mexsol | Bin 0 -> 27012 bytes .../common/toolbox/toolbox_basic/common/writepdm.m | 11 + .../common/toolbox/toolbox_basic/common/writepfm.m | 11 + .../common/toolbox/toolbox_basic/disp/disp_image.m | 19 + .../common/toolbox/toolbox_basic/disp/draw_box.m | 9 + .../common/toolbox/toolbox_basic/disp/draw_box2.m | 17 + SD-VBS/common/toolbox/toolbox_basic/disp/im.m | 8 + SD-VBS/common/toolbox/toolbox_basic/disp/ims.m | 3 + .../common/toolbox/toolbox_basic/disp/montage2.m | 17 + .../common/toolbox/toolbox_basic/disp/showmask.m | 20 + .../common/toolbox/toolbox_basic/disp/showmaskb.m | 20 + .../toolbox/toolbox_basic/fact/construct_w.m | 25 + .../toolbox/toolbox_basic/fact/construct_w2.m | 25 + SD-VBS/common/toolbox/toolbox_basic/fact/factor.m | 50 + .../toolbox/toolbox_basic/fact/factor_test.m | 52 + .../toolbox/toolbox_basic/fact/factor_test2.m | 52 + .../toolbox/toolbox_basic/fact/factorizaion.tar | Bin 0 -> 81920 bytes SD-VBS/common/toolbox/toolbox_basic/fact/findG.m | 48 + SD-VBS/common/toolbox/toolbox_basic/fact/findg1.m | 49 + SD-VBS/common/toolbox/toolbox_basic/fact/findg2.m | 56 + SD-VBS/common/toolbox/toolbox_basic/fact/hotel.mat | Bin 0 -> 56320 bytes .../toolbox/toolbox_basic/fact/show_3dpoints.m | 22 + SD-VBS/common/toolbox/toolbox_basic/fact/show_S.m | 17 + SD-VBS/common/toolbox/toolbox_basic/fact/show_t.m | 10 + SD-VBS/common/toolbox/toolbox_basic/fact/show_t3.m | 10 + SD-VBS/common/toolbox/toolbox_basic/fact/zt.m | 6 + .../common/toolbox/toolbox_basic/filter/91048.jpg | Bin 0 -> 2553 bytes SD-VBS/common/toolbox/toolbox_basic/filter/bar2d.m | 16 + .../common/toolbox/toolbox_basic/filter/barrot.m | 22 + SD-VBS/common/toolbox/toolbox_basic/filter/bars.m | 39 + .../toolbox/toolbox_basic/filter/clip_image.m | 6 + .../toolbox_basic/filter/compute_J_simple.m | 50 + .../toolbox/toolbox_basic/filter/compute_angle.m | 18 + .../toolbox_basic/filter/compute_filter_fft.m | 84 + .../toolbox/toolbox_basic/filter/compute_g2.m | 23 + .../toolbox/toolbox_basic/filter/compute_h2.m | 27 + .../toolbox_basic/filter/compute_ofilter_fft.m | 88 + .../common/toolbox/toolbox_basic/filter/dgauss.m | 16 + SD-VBS/common/toolbox/toolbox_basic/filter/dog1.m | 28 + SD-VBS/common/toolbox/toolbox_basic/filter/dog2.m | 31 + SD-VBS/common/toolbox/toolbox_basic/filter/doog1.m | 32 + SD-VBS/common/toolbox/toolbox_basic/filter/doog2.m | 38 + .../common/toolbox/toolbox_basic/filter/fft_filt.m | 82 + .../toolbox/toolbox_basic/filter/fft_filt_2.m | 29 + .../toolbox_basic/filter/filter_bank_jshi.tar | Bin 0 -> 71680 bytes SD-VBS/common/toolbox/toolbox_basic/filter/gauss.m | 16 + .../common/toolbox/toolbox_basic/filter/gaussian.m | 31 + .../toolbox/toolbox_basic/filter/get_diff2.m | 43 + .../toolbox/toolbox_basic/filter/get_diff_free.m | 8 + SD-VBS/common/toolbox/toolbox_basic/filter/grad1.m | 11 + SD-VBS/common/toolbox/toolbox_basic/filter/grad2.m | 11 + .../toolbox/toolbox_basic/filter/m_interp4.m | 49 + .../toolbox/toolbox_basic/filter/make_filterbank.m | 63 + .../toolbox_basic/filter/make_filterbank_23.m | 40 + .../toolbox_basic/filter/make_filterbank_even.m | 40 + .../toolbox_basic/filter/make_filterbank_odd.m | 41 + .../common/toolbox/toolbox_basic/filter/mdoog2.m | 36 + .../toolbox/toolbox_basic/filter/mimrotate.m | 119 + .../toolbox/toolbox_basic/filter/mk_odd_filter.m | 36 + .../common/toolbox/toolbox_basic/filter/mkdog1.m | 20 + .../common/toolbox/toolbox_basic/filter/mkdog2.m | 22 + .../common/toolbox/toolbox_basic/filter/mkdoog2.m | 30 + .../common/toolbox/toolbox_basic/filter/mkdoogs.m | 15 + SD-VBS/common/toolbox/toolbox_basic/filter/mkg.m | 9 + .../common/toolbox/toolbox_basic/filter/quadpair.m | 20 + .../common/toolbox/toolbox_basic/filter/smooth.m | 24 + .../toolbox/toolbox_basic/filter/softkmean.m | 56 + .../toolbox/toolbox_basic/filter/softmeans.m | 46 + .../toolbox/toolbox_basic/filter/softmeans2.m | 39 + SD-VBS/common/toolbox/toolbox_basic/filterQuad.zip | Bin 0 -> 4531 bytes .../toolbox/toolbox_basic/filter_hist/1d_cut.m | 16 + .../toolbox/toolbox_basic/filter_hist/Bfilter.m | 11 + .../toolbox/toolbox_basic/filter_hist/BfilterS.m | 17 + .../toolbox/toolbox_basic/filter_hist/Ncut.m | 14 + .../toolbox_basic/filter_hist/apply_image.m | 38 + .../toolbox/toolbox_basic/filter_hist/back_proj.m | 10 + .../toolbox_basic/filter_hist/backproj_outer.m | 9 + .../filter_hist/backproj_outer_chank.m | 33 + .../filter_hist/backproj_outer_chank2.m | 36 + .../toolbox/toolbox_basic/filter_hist/binize.m | 15 + .../toolbox/toolbox_basic/filter_hist/binize_old.m | 34 + .../toolbox_basic/filter_hist/binomialfield.m | 75 + .../toolbox/toolbox_basic/filter_hist/colize.m | 9 + .../toolbox_basic/filter_hist/colize_hist.m | 29 + .../toolbox_basic/filter_hist/colize_histnb_s.m | 47 + .../toolbox_basic/filter_hist/colize_histnb_sf.m | 52 + .../toolbox_basic/filter_hist/colize_histneighb.m | 37 + .../toolbox_basic/filter_hist/colize_joint_hist.m | 41 + .../toolbox_basic/filter_hist/colize_test.m | 19 + .../toolbox/toolbox_basic/filter_hist/compact.m | 36 + .../toolbox/toolbox_basic/filter_hist/compute_J.m | 31 + .../toolbox/toolbox_basic/filter_hist/compute_Lf.m | 35 + .../toolbox_basic/filter_hist/compute_corr.m | 10 + .../toolbox_basic/filter_hist/compute_diff.m | 36 + .../toolbox_basic/filter_hist/compute_diff_patch.m | 34 + .../filter_hist/compute_diff_patch2.m | 45 + .../toolbox_basic/filter_hist/compute_filter.m | 84 + .../toolbox_basic/filter_hist/compute_filter_fft.m | 84 + .../toolbox/toolbox_basic/filter_hist/conv_trim.m | 6 + .../toolbox/toolbox_basic/filter_hist/corr_hist.m | 9 + .../toolbox_basic/filter_hist/crop_im_fil.m | 11 + .../toolbox/toolbox_basic/filter_hist/cutoff.m | 13 + .../toolbox/toolbox_basic/filter_hist/cutout.m | 3 + .../toolbox/toolbox_basic/filter_hist/disp_Imask.m | 20 + .../toolbox/toolbox_basic/filter_hist/disp_diff.m | 37 + .../toolbox_basic/filter_hist/disp_evresult.m | 435 +++ .../toolbox_basic/filter_hist/disp_evresult2.m | 215 ++ .../toolbox_basic/filter_hist/disp_evresulthome.m | 237 ++ .../toolbox_basic/filter_hist/disp_groups.m | 13 + .../toolbox_basic/filter_hist/disp_hist2d.m | 15 + .../toolbox/toolbox_basic/filter_hist/dist_pair.m | 28 + .../toolbox_basic/filter_hist/dist_pair_chank.m | 25 + .../toolbox/toolbox_basic/filter_hist/doog2.m | 43 + .../toolbox/toolbox_basic/filter_hist/eig_decomp.m | 15 + .../toolbox_basic/filter_hist/eig_decomp_v5.m | 13 + .../toolbox/toolbox_basic/filter_hist/eig_proj.m | 12 + .../toolbox_basic/filter_hist/eigs_decomp.m | 39 + .../toolbox_basic/filter_hist/euclid_dist.m | 22 + .../toolbox_basic/filter_hist/filter_all_files.m | 29 + .../toolbox_basic/filter_hist/filter_output.m | 38 + .../toolbox_basic/filter_hist/find_bst_cut.m | 24 + .../toolbox_basic/filter_hist/find_center.m | 4 + .../toolbox_basic/filter_hist/find_cutpoint.m | 13 + .../toolbox_basic/filter_hist/gen_filters.m | 47 + .../toolbox_basic/filter_hist/get_cumhist.m | 9 + .../toolbox_basic/filter_hist/get_cumhist_inten.m | 7 + .../toolbox/toolbox_basic/filter_hist/get_hist.m | 24 + .../toolbox_basic/filter_hist/get_hist_inten.m | 15 + .../toolbox/toolbox_basic/filter_hist/get_win.m | 10 + .../toolbox/toolbox_basic/filter_hist/get_win5.m | 11 + .../toolbox/toolbox_basic/filter_hist/grad.m | 24 + .../toolbox_basic/filter_hist/half_sigmoid.m | 17 + .../toolbox/toolbox_basic/filter_hist/hist2d.m | 13 + .../toolbox/toolbox_basic/filter_hist/hist_I_f.m | 22 + .../toolbox/toolbox_basic/filter_hist/hist_diff.m | 30 + .../toolbox/toolbox_basic/filter_hist/hist_f.m | 28 + .../toolbox_basic/filter_hist/hist_in_chank.m | 33 + .../toolbox/toolbox_basic/filter_hist/hist_inner.m | 40 + .../toolbox_basic/filter_hist/histbin_fv_chank.m | 14 + .../toolbox/toolbox_basic/filter_hist/hsv2clrs.m | 25 + .../toolbox/toolbox_basic/filter_hist/id_cut.m | 14 + .../common/toolbox/toolbox_basic/filter_hist/im.m | 3 + .../common/toolbox/toolbox_basic/filter_hist/im3.m | 3 + .../common/toolbox/toolbox_basic/filter_hist/im5.m | 16 + .../toolbox/toolbox_basic/filter_hist/im_vect.m | 20 + .../toolbox/toolbox_basic/filter_hist/imrotate.m | 119 + .../common/toolbox/toolbox_basic/filter_hist/ims.m | 3 + .../toolbox/toolbox_basic/filter_hist/imvs.m | 4 + .../toolbox/toolbox_basic/filter_hist/is_step.m | 33 + .../toolbox/toolbox_basic/filter_hist/ks_2d.m | 20 + .../toolbox_basic/filter_hist/load_result.m | 39 + .../toolbox/toolbox_basic/filter_hist/m_interp4.m | 49 + .../toolbox/toolbox_basic/filter_hist/make_masks.m | 12 + .../toolbox/toolbox_basic/filter_hist/makefilter.m | 14 + .../toolbox/toolbox_basic/filter_hist/mkf_t1.m | 22 + .../toolbox/toolbox_basic/filter_hist/mkf_t2.m | 21 + .../toolbox/toolbox_basic/filter_hist/mkf_test.m | 43 + .../common/toolbox/toolbox_basic/filter_hist/mkg.m | 9 + .../toolbox/toolbox_basic/filter_hist/mkgaussian.m | 11 + .../toolbox_basic/filter_hist/mkmulfilter.m | 52 + .../toolbox/toolbox_basic/filter_hist/mkpoog2.m | 29 + .../toolbox/toolbox_basic/filter_hist/mksgn.m | 10 + .../toolbox/toolbox_basic/filter_hist/mksgn2.m | 9 + .../toolbox/toolbox_basic/filter_hist/mreadpfm.m | 11 + .../toolbox/toolbox_basic/filter_hist/mreadpfm2.m | 9 + .../toolbox/toolbox_basic/filter_hist/mwis.m | 16 + .../toolbox/toolbox_basic/filter_hist/mwis_image.m | 25 + .../toolbox/toolbox_basic/filter_hist/myinterp.m | 18 + .../toolbox/toolbox_basic/filter_hist/ncut_b.m | 25 + .../toolbox_basic/filter_hist/new_compute_J.m | 32 + .../toolbox/toolbox_basic/filter_hist/pair_dist.m | 45 + .../toolbox/toolbox_basic/filter_hist/pair_dist2.m | 46 + .../toolbox_basic/filter_hist/pair_dist_text.m | 70 + .../toolbox_basic/filter_hist/pair_dist_text2.m | 58 + .../toolbox_basic/filter_hist/pair_dist_text3.m | 84 + .../toolbox_basic/filter_hist/pair_dist_text4.m | 81 + .../toolbox/toolbox_basic/filter_hist/patch_cat.m | 9 + .../toolbox/toolbox_basic/filter_hist/pgmread.m | 15 + .../toolbox/toolbox_basic/filter_hist/poisson.m | 44 + .../toolbox_basic/filter_hist/poissonfield.m | 53 + .../toolbox/toolbox_basic/filter_hist/proj_back.m | 24 + .../toolbox_basic/filter_hist/proj_back_id.m | 19 + .../toolbox/toolbox_basic/filter_hist/quant.m | 20 + .../toolbox/toolbox_basic/filter_hist/readpdm.m | 8 + .../toolbox/toolbox_basic/filter_hist/readpfm.m | 10 + .../toolbox/toolbox_basic/filter_hist/readpfm_id.m | 21 + .../toolbox_basic/filter_hist/readpfm_idf.m | 29 + .../toolbox/toolbox_basic/filter_hist/readpgm.m | 26 + .../toolbox/toolbox_basic/filter_hist/readpnm.m | 21 + .../toolbox/toolbox_basic/filter_hist/readppm.m | 19 + .../toolbox/toolbox_basic/filter_hist/record.m | 6 + .../toolbox_basic/filter_hist/recursive_cut_tc.m | 140 + .../toolbox/toolbox_basic/filter_hist/reduce_all.m | 8 + .../toolbox/toolbox_basic/filter_hist/rotate_J.m | 30 + .../toolbox/toolbox_basic/filter_hist/session.m | 4 + .../toolbox_basic/filter_hist/show_cumhist.m | 28 + .../toolbox/toolbox_basic/filter_hist/show_hist.m | 23 + .../toolbox/toolbox_basic/filter_hist/showsmm.m | 45 + .../toolbox/toolbox_basic/filter_hist/showsmm_v5.m | 34 + .../toolbox/toolbox_basic/filter_hist/sigmoid.m | 10 + .../toolbox/toolbox_basic/filter_hist/signif.m | 22 + .../toolbox/toolbox_basic/filter_hist/signif_N.m | 10 + .../toolbox/toolbox_basic/filter_hist/smooth.m | 20 + .../toolbox/toolbox_basic/filter_hist/startup.m | 9 + .../toolbox/toolbox_basic/filter_hist/swarp.m | 9 + .../toolbox/toolbox_basic/filter_hist/swarpback.m | 12 + .../toolbox/toolbox_basic/filter_hist/test.m | 110 + .../toolbox/toolbox_basic/filter_hist/test1.m | 175 ++ .../toolbox/toolbox_basic/filter_hist/test2.m | 220 ++ .../toolbox/toolbox_basic/filter_hist/test3.m | 4 + .../toolbox_basic/filter_hist/test_best_cut.m | 12 + .../toolbox/toolbox_basic/filter_hist/test_evtex.m | 361 +++ .../toolbox_basic/filter_hist/test_evtex2.m | 136 + .../toolbox_basic/filter_hist/test_evtex3.m | 169 ++ .../toolbox_basic/filter_hist/test_evtex4.m | 353 +++ .../toolbox_basic/filter_hist/test_evtex5.m | 446 +++ .../toolbox_basic/filter_hist/test_motion.m | 117 + .../toolbox_basic/filter_hist/test_motion2.m | 127 + .../toolbox_basic/filter_hist/test_period.m | 58 + .../toolbox/toolbox_basic/filter_hist/test_text.m | 434 +++ .../common/toolbox/toolbox_basic/filter_hist/tmp.m | 68 + .../toolbox/toolbox_basic/filter_hist/tmp1.m | 25 + .../toolbox/toolbox_basic/filter_hist/tmp2.m | 17 + .../toolbox/toolbox_basic/filter_hist/tmp3.m | 126 + .../toolbox/toolbox_basic/filter_hist/true_loc.m | 23 + .../toolbox/toolbox_basic/filter_hist/vmquant.m | 112 + .../toolbox/toolbox_basic/filter_hist/wismm.m | 26 + .../toolbox/toolbox_basic/filter_hist/wismm2.m | 66 + .../toolbox/toolbox_basic/filter_hist/wismm3.m | 71 + .../toolbox_basic/filter_hist/write_command.m | 8 + .../toolbox/toolbox_basic/filter_hist/write_test.m | 38 + .../toolbox_basic/filter_hist/writeout_feature.m | 40 + .../toolbox/toolbox_basic/filter_hist/writepfm.m | 11 + .../toolbox/toolbox_basic/filter_hist/writepgm.m | 8 + .../toolbox/toolbox_basic/filter_hist/writepmm.m | 14 + .../toolbox/toolbox_basic/filter_hist/writepnm5.m | 26 + .../toolbox/toolbox_basic/filtersQuad/doog1.m | 32 + .../toolbox/toolbox_basic/filtersQuad/doog2.m | 38 + .../filtersQuad/make_filterbank_even2.m | 45 + .../filtersQuad/make_filterbank_odd2.m | 46 + .../toolbox/toolbox_basic/filtersQuad/quadedgep2.m | 188 ++ .../common/toolbox/toolbox_basic/io/convert422.m | 27 + SD-VBS/common/toolbox/toolbox_basic/io/im_vd.m | 6 + SD-VBS/common/toolbox/toolbox_basic/io/imread2.m | 45 + .../toolbox/toolbox_basic/io/peek_pgm_size.m | 19 + SD-VBS/common/toolbox/toolbox_basic/io/pgmread.m | 24 + SD-VBS/common/toolbox/toolbox_basic/io/ppmtojpg.m | 25 + SD-VBS/common/toolbox/toolbox_basic/io/read422.m | 45 + SD-VBS/common/toolbox/toolbox_basic/io/read422f.m | 50 + .../common/toolbox/toolbox_basic/io/read_cimgs.m | 40 + .../common/toolbox/toolbox_basic/io/read_ev_pgm.m | 26 + .../common/toolbox/toolbox_basic/io/read_ev_pgm2.m | 29 + .../toolbox/toolbox_basic/io/read_ev_pgm_real.m | 30 + SD-VBS/common/toolbox/toolbox_basic/io/read_imgs.m | 47 + SD-VBS/common/toolbox/toolbox_basic/io/read_pmm.m | 12 + SD-VBS/common/toolbox/toolbox_basic/io/read_scan.m | 42 + .../toolbox/toolbox_basic/io/read_seg_file.m | 36 + SD-VBS/common/toolbox/toolbox_basic/io/readlines.m | 30 + SD-VBS/common/toolbox/toolbox_basic/io/readpdm3.m | 16 + SD-VBS/common/toolbox/toolbox_basic/io/readpdmc.m | 12 + SD-VBS/common/toolbox/toolbox_basic/io/readpfm.m | 10 + SD-VBS/common/toolbox/toolbox_basic/io/readpfm3.m | 17 + SD-VBS/common/toolbox/toolbox_basic/io/readpfmc.m | 11 + SD-VBS/common/toolbox/toolbox_basic/io/readpgm.m | 30 + .../toolbox/toolbox_basic/io/readpgm_evinfo.m | 35 + SD-VBS/common/toolbox/toolbox_basic/io/readpmm.m | 22 + SD-VBS/common/toolbox/toolbox_basic/io/readppm.m | 23 + SD-VBS/common/toolbox/toolbox_basic/io/writepgm.m | 8 + SD-VBS/common/toolbox/toolbox_basic/io/writeppm.m | 14 + .../pub/contrib/v5/optim/assignprob/Contents.m | 26 + .../pub/contrib/v5/optim/assignprob/allcosts.m | 17 + .../pub/contrib/v5/optim/assignprob/allperm.m | 17 + .../pub/contrib/v5/optim/assignprob/condass.m | 54 + .../pub/contrib/v5/optim/assignprob/demo.m | 38 + .../pub/contrib/v5/optim/assignprob/hungarian.m | 464 +++ .../pub/contrib/v5/optim/assignprob/test.m | 87 + .../toolbox_basic/pyramid/091399fbn-jets.3.jpg | Bin 0 -> 25886 bytes .../common/toolbox/toolbox_basic/pyramid/expand.m | 8 + .../toolbox/toolbox_basic/pyramid/gauss_lowpass.m | 9 + .../common/toolbox/toolbox_basic/pyramid/gen_w.m | 12 + .../common/toolbox/toolbox_basic/pyramid/reduce.m | 7 + .../common/toolbox/toolbox_basic/pyramid/session.m | 26 + .../common/toolbox/toolbox_basic/pyramid/startup.m | 5 + SD-VBS/common/toolbox/toolbox_basic/remap_angle.m | 4 + SD-VBS/common/toolbox/toolbox_basic/spmtimesd.c | 141 + .../toolbox/toolbox_basic/stella/afromncut.m | 73 + .../common/toolbox/toolbox_basic/stella/dispimg.m | 65 + .../toolbox/toolbox_basic/stella/firstncut.m | 67 + .../toolbox/toolbox_basic/stella/getfnames.m | 47 + .../toolbox/toolbox_basic/stella/getimage2.m | 46 + .../toolbox/toolbox_basic/stella/globalenvar.m | 6 + .../common/toolbox/toolbox_basic/stella/jshincut.m | 94 + .../toolbox/toolbox_basic/stella/jshincutdefpar.m | 20 + .../toolbox/toolbox_basic/stella/ncutcheckin.m | 136 + .../toolbox/toolbox_basic/stella/openfigure.m | 52 + .../common/toolbox/toolbox_basic/stella/showim.m | 36 + .../common/toolbox/toolbox_basic/stella/showncut.m | 92 + .../common/toolbox/toolbox_basic/stella/startup.m | 18 + .../toolbox/toolbox_basic/stella/test_ncutm.m | 38 + .../toolbox/toolbox_basic/tars/TOOLBOX_calib.tar | Bin 0 -> 253952 bytes .../common/toolbox/toolbox_basic/textons/dist2.m | 27 + .../toolbox/toolbox_basic/textons/find_textons.m | 46 + .../toolbox/toolbox_basic/textons/find_textons1.m | 37 + .../common/toolbox/toolbox_basic/textons/kmeans2.m | 127 + 752 files changed, 48920 insertions(+) create mode 100644 SD-VBS/common/c/calcSobel_dX.c create mode 100644 SD-VBS/common/c/calcSobel_dY.c create mode 100644 SD-VBS/common/c/extra.h create mode 100644 SD-VBS/common/c/fCopy.c create mode 100644 SD-VBS/common/c/fDeepCopy.c create mode 100644 SD-VBS/common/c/fDeepCopyRange.c create mode 100644 SD-VBS/common/c/fDivide.c create mode 100644 SD-VBS/common/c/fFind3.c create mode 100644 SD-VBS/common/c/fFreeHandle.c create mode 100644 SD-VBS/common/c/fHorzcat.c create mode 100644 SD-VBS/common/c/fMallocHandle.c create mode 100644 SD-VBS/common/c/fMdivide.c create mode 100644 SD-VBS/common/c/fMinus.c create mode 100644 SD-VBS/common/c/fMtimes.c create mode 100644 SD-VBS/common/c/fPlus.c create mode 100644 SD-VBS/common/c/fResetArray.c create mode 100644 SD-VBS/common/c/fResetHandle.c create mode 100644 SD-VBS/common/c/fReshape.c create mode 100644 SD-VBS/common/c/fResortIndices.c create mode 100644 SD-VBS/common/c/fSelfCheck.c create mode 100644 SD-VBS/common/c/fSetArray.c create mode 100644 SD-VBS/common/c/fSort.c create mode 100644 SD-VBS/common/c/fSortIndices.c create mode 100644 SD-VBS/common/c/fSum.c create mode 100644 SD-VBS/common/c/fSum2.c create mode 100644 SD-VBS/common/c/fTimes.c create mode 100644 SD-VBS/common/c/fTranspose.c create mode 100644 SD-VBS/common/c/fWriteMatrix.c create mode 100644 SD-VBS/common/c/ffConv2.c create mode 100644 SD-VBS/common/c/ffConv2_dY.c create mode 100644 SD-VBS/common/c/ffDivide.c create mode 100644 SD-VBS/common/c/ffTimes.c create mode 100644 SD-VBS/common/c/ffVertcat.c create mode 100644 SD-VBS/common/c/ffiConv2.c create mode 100644 SD-VBS/common/c/fiConv2.c create mode 100644 SD-VBS/common/c/fiCopy.c create mode 100644 SD-VBS/common/c/fiDeepCopy.c create mode 100644 SD-VBS/common/c/horzcat.c create mode 100644 SD-VBS/common/c/iCheck.c create mode 100644 SD-VBS/common/c/iDeepCopy.c create mode 100644 SD-VBS/common/c/iDeepCopyRange.c create mode 100644 SD-VBS/common/c/iFreeHandle.c create mode 100644 SD-VBS/common/c/iHorzcat.c create mode 100644 SD-VBS/common/c/iMallocHandle.c create mode 100644 SD-VBS/common/c/iMinus.c create mode 100644 SD-VBS/common/c/iResetArray.c create mode 100644 SD-VBS/common/c/iReshape.c create mode 100644 SD-VBS/common/c/iSetArray.c create mode 100644 SD-VBS/common/c/iSort.c create mode 100644 SD-VBS/common/c/iSortIndices.c create mode 100644 SD-VBS/common/c/iTimes.c create mode 100644 SD-VBS/common/c/iTranspose.c create mode 100644 SD-VBS/common/c/iVertcat.c create mode 100644 SD-VBS/common/c/ifDeepCopy.c create mode 100644 SD-VBS/common/c/ifMtimes.c create mode 100644 SD-VBS/common/c/iiConv2.c create mode 100644 SD-VBS/common/c/imageBlur.c create mode 100644 SD-VBS/common/c/imageReblur.c create mode 100644 SD-VBS/common/c/imageResize.c create mode 100644 SD-VBS/common/c/isMinus.c create mode 100644 SD-VBS/common/c/isPlus.c create mode 100644 SD-VBS/common/c/photonEndTiming.c create mode 100644 SD-VBS/common/c/photonPrintTiming.c create mode 100644 SD-VBS/common/c/photonReportTiming.c create mode 100644 SD-VBS/common/c/photonStartTiming.c create mode 100644 SD-VBS/common/c/randWrapper.c create mode 100644 SD-VBS/common/c/randnWrapper.c create mode 100644 SD-VBS/common/c/readFile.c create mode 100644 SD-VBS/common/c/readImage.c create mode 100644 SD-VBS/common/c/sdvbs_common.h create mode 100644 SD-VBS/common/c/selfCheck.c create mode 100644 SD-VBS/common/c/timingUtils.h create mode 100644 SD-VBS/common/c/uiFreeHandle.c create mode 100644 SD-VBS/common/c/uiMallocHandle.c create mode 100644 SD-VBS/common/c/uiResetArray.c create mode 100644 SD-VBS/common/c/uiSetArray.c create mode 100644 SD-VBS/common/c/writeMatrix.c create mode 100644 SD-VBS/common/makefiles/Makefile.common create mode 100644 SD-VBS/common/makefiles/Makefile.include create mode 100644 SD-VBS/common/makefiles/Makefile.recurse create mode 100644 SD-VBS/common/support/buildTable.py create mode 100644 SD-VBS/common/support/buildTimeTable.py create mode 100755 SD-VBS/common/toolbox/MultiNcut/MNcut.m create mode 100755 SD-VBS/common/toolbox/MultiNcut/MNcutDemo.m create mode 100755 SD-VBS/common/toolbox/MultiNcut/README.tex create mode 100755 SD-VBS/common/toolbox/MultiNcut/a_times_b_cmplx.c create mode 100755 SD-VBS/common/toolbox/MultiNcut/a_times_b_cmplx.dll create mode 100755 SD-VBS/common/toolbox/MultiNcut/a_times_b_cmplx.mexa64 create mode 100755 SD-VBS/common/toolbox/MultiNcut/a_times_b_cmplx.mexglx create mode 100755 SD-VBS/common/toolbox/MultiNcut/a_times_b_cmplx.mexmac create mode 100755 SD-VBS/common/toolbox/MultiNcut/affinityic.c create mode 100755 SD-VBS/common/toolbox/MultiNcut/affinityic.dll create mode 100755 SD-VBS/common/toolbox/MultiNcut/affinityic.mexa64 create mode 100755 SD-VBS/common/toolbox/MultiNcut/affinityic.mexglx create mode 100755 SD-VBS/common/toolbox/MultiNcut/batch_MNcut.m create mode 100755 SD-VBS/common/toolbox/MultiNcut/cimgnbmap.c create mode 100755 SD-VBS/common/toolbox/MultiNcut/cimgnbmap.dll create mode 100755 SD-VBS/common/toolbox/MultiNcut/cimgnbmap.mexa64 create mode 100755 SD-VBS/common/toolbox/MultiNcut/cimgnbmap.mexglx create mode 100755 SD-VBS/common/toolbox/MultiNcut/cimgnbmap_cross.c create mode 100755 SD-VBS/common/toolbox/MultiNcut/cimgnbmap_cross.dll create mode 100755 SD-VBS/common/toolbox/MultiNcut/cimgnbmap_cross.mexa64 create mode 100755 SD-VBS/common/toolbox/MultiNcut/cimgnbmap_cross.mexglx create mode 100755 SD-VBS/common/toolbox/MultiNcut/cimgnbmap_star.c create mode 100755 SD-VBS/common/toolbox/MultiNcut/cimgnbmap_star.dll create mode 100755 SD-VBS/common/toolbox/MultiNcut/cimgnbmap_star.mexa64 create mode 100755 SD-VBS/common/toolbox/MultiNcut/cimgnbmap_star.mexglx create mode 100755 SD-VBS/common/toolbox/MultiNcut/compileAll.m create mode 100755 SD-VBS/common/toolbox/MultiNcut/computeMultiW.m create mode 100755 SD-VBS/common/toolbox/MultiNcut/discretisation.m create mode 100755 SD-VBS/common/toolbox/MultiNcut/discretisationEigenVectorData.m create mode 100755 SD-VBS/common/toolbox/MultiNcut/doog1.m create mode 100755 SD-VBS/common/toolbox/MultiNcut/doog2.m create mode 100755 SD-VBS/common/toolbox/MultiNcut/eigSolve.m create mode 100755 SD-VBS/common/toolbox/MultiNcut/fft_filt_2.m create mode 100755 SD-VBS/common/toolbox/MultiNcut/gaussian.m create mode 100755 SD-VBS/common/toolbox/MultiNcut/make_filterbank_even2.m create mode 100755 SD-VBS/common/toolbox/MultiNcut/make_filterbank_odd2.m create mode 100755 SD-VBS/common/toolbox/MultiNcut/mex_projection_QR.c create mode 100755 SD-VBS/common/toolbox/MultiNcut/mex_projection_QR.dll create mode 100755 SD-VBS/common/toolbox/MultiNcut/mex_projection_QR.mexa64 create mode 100755 SD-VBS/common/toolbox/MultiNcut/mex_projection_QR.mexglx create mode 100755 SD-VBS/common/toolbox/MultiNcut/mex_projection_QR_symmetric.c create mode 100755 SD-VBS/common/toolbox/MultiNcut/mex_projection_QR_symmetric.dll create mode 100755 SD-VBS/common/toolbox/MultiNcut/mex_projection_QR_symmetric.mexa64 create mode 100755 SD-VBS/common/toolbox/MultiNcut/mex_projection_QR_symmetric.mexglx create mode 100755 SD-VBS/common/toolbox/MultiNcut/mex_w_times_x_symmetric.mexglx create mode 100755 SD-VBS/common/toolbox/MultiNcut/mex_w_times_x_symmetric.mexmac create mode 100755 SD-VBS/common/toolbox/MultiNcut/multiAffinityic.c create mode 100755 SD-VBS/common/toolbox/MultiNcut/multiAffinityic.dll create mode 100755 SD-VBS/common/toolbox/MultiNcut/multiAffinityic.mexa64 create mode 100755 SD-VBS/common/toolbox/MultiNcut/multiAffinityic.mexglx create mode 100755 SD-VBS/common/toolbox/MultiNcut/multiIntensityFirstLayer.c create mode 100755 SD-VBS/common/toolbox/MultiNcut/multiIntensityFirstLayer.dll create mode 100755 SD-VBS/common/toolbox/MultiNcut/multiIntensityFirstLayer.mexa64 create mode 100755 SD-VBS/common/toolbox/MultiNcut/multiIntensityFirstLayer.mexglx create mode 100755 SD-VBS/common/toolbox/MultiNcut/multiIntensityWppc.c create mode 100755 SD-VBS/common/toolbox/MultiNcut/multiIntensityWppc.dll create mode 100755 SD-VBS/common/toolbox/MultiNcut/multiIntensityWppc.mexa64 create mode 100755 SD-VBS/common/toolbox/MultiNcut/multiIntensityWppc.mexglx create mode 100755 SD-VBS/common/toolbox/MultiNcut/quadedgep2.m create mode 100755 SD-VBS/common/toolbox/MultiNcut/quickNcutHardBiais2.m create mode 100755 SD-VBS/common/toolbox/MultiNcut/read_data.m create mode 100755 SD-VBS/common/toolbox/MultiNcut/readimage.m create mode 100755 SD-VBS/common/toolbox/MultiNcut/run_script.m create mode 100755 SD-VBS/common/toolbox/MultiNcut/showmask.m create mode 100755 SD-VBS/common/toolbox/MultiNcut/sparsifyc.c create mode 100755 SD-VBS/common/toolbox/MultiNcut/sparsifyc.dll create mode 100755 SD-VBS/common/toolbox/MultiNcut/sparsifyc.mexa64 create mode 100755 SD-VBS/common/toolbox/MultiNcut/sparsifyc.mexglx create mode 100755 SD-VBS/common/toolbox/MultiNcut/sparsifyc.mexmac create mode 100755 SD-VBS/common/toolbox/MultiNcut/spmtimesd.c create mode 100755 SD-VBS/common/toolbox/MultiNcut/spmtimesd.dll create mode 100755 SD-VBS/common/toolbox/MultiNcut/spmtimesd.mexa64 create mode 100755 SD-VBS/common/toolbox/MultiNcut/spmtimesd.mexglx create mode 100755 SD-VBS/common/toolbox/MultiNcut/spmtimesd.mexmac create mode 100755 SD-VBS/common/toolbox/MultiNcut/tim_eigs.m create mode 100755 SD-VBS/common/toolbox/ikkjin/getANMS.m create mode 100755 SD-VBS/common/toolbox/ikkjin/getImgGrad.m create mode 100755 SD-VBS/common/toolbox/ikkjin/harris.m create mode 100755 SD-VBS/common/toolbox/lagrcv/Makefile create mode 100755 SD-VBS/common/toolbox/lagrcv/README.sxw create mode 100755 SD-VBS/common/toolbox/lagrcv/calcGradientPyrMex.cc create mode 100755 SD-VBS/common/toolbox/lagrcv/calcGradientPyrMex.mexa64 create mode 100755 SD-VBS/common/toolbox/lagrcv/calcGradientPyrMex.mexglx create mode 100755 SD-VBS/common/toolbox/lagrcv/calcImgBlurMex.cc create mode 100755 SD-VBS/common/toolbox/lagrcv/calcImgBlurMex.mexa64 create mode 100755 SD-VBS/common/toolbox/lagrcv/calcImgBlurMex.mexglx create mode 100755 SD-VBS/common/toolbox/lagrcv/calcOptFlowLKMex.cc create mode 100755 SD-VBS/common/toolbox/lagrcv/calcOptFlowLKMex.mexa64 create mode 100755 SD-VBS/common/toolbox/lagrcv/calcOptFlowLKMex.mexglx create mode 100755 SD-VBS/common/toolbox/lagrcv/calcOptFlowLKPyrMex.cc create mode 100755 SD-VBS/common/toolbox/lagrcv/calcOptFlowLKPyrMex.mexa64 create mode 100755 SD-VBS/common/toolbox/lagrcv/calcOptFlowLKPyrMex.mexglx create mode 100755 SD-VBS/common/toolbox/lagrcv/calcOptFlowLKPyrMex2.cc create mode 100755 SD-VBS/common/toolbox/lagrcv/calcOptFlowLKPyrMex2.mexa64 create mode 100755 SD-VBS/common/toolbox/lagrcv/calcOptFlowLKPyrMex2.mexglx create mode 100755 SD-VBS/common/toolbox/lagrcv/calcOptFlowLKPyrWInitMex.cc create mode 100755 SD-VBS/common/toolbox/lagrcv/calcOptFlowLKPyrWInitMex.mexa64 create mode 100755 SD-VBS/common/toolbox/lagrcv/calcOptFlowLKPyrWInitMex.mexglx create mode 100755 SD-VBS/common/toolbox/lagrcv/calcOptFlowLKPyrWInitMex2.cc create mode 100755 SD-VBS/common/toolbox/lagrcv/calcOptFlowLKPyrWInitMex2.mexa64 create mode 100755 SD-VBS/common/toolbox/lagrcv/calcOptFlowLKPyrWInitMex2.mexglx create mode 100755 SD-VBS/common/toolbox/lagrcv/calcOptFlowLKPyrWInitSobelMex.cc create mode 100755 SD-VBS/common/toolbox/lagrcv/calcOptFlowLKPyrWInitSobelMex.mexa64 create mode 100755 SD-VBS/common/toolbox/lagrcv/calcOptFlowLKPyrWInitSobelMex.mexglx create mode 100755 SD-VBS/common/toolbox/lagrcv/calcOpticalFlowLK.cc create mode 100755 SD-VBS/common/toolbox/lagrcv/calcOpticalFlowPyrLK.cc create mode 100755 SD-VBS/common/toolbox/lagrcv/calcOpticalFlowPyrLK.mexglx create mode 100755 SD-VBS/common/toolbox/lagrcv/calcResizedImgMex.cc create mode 100755 SD-VBS/common/toolbox/lagrcv/calcResizedImgMex.mexa64 create mode 100755 SD-VBS/common/toolbox/lagrcv/calcResizedImgMex.mexglx create mode 100755 SD-VBS/common/toolbox/lagrcv/calcSobelMex.cc create mode 100755 SD-VBS/common/toolbox/lagrcv/calcSobelMex.mexa64 create mode 100755 SD-VBS/common/toolbox/lagrcv/calcSobelMex.mexglx create mode 100755 SD-VBS/common/toolbox/lagrcv/calcSobelPyrMex.cc create mode 100755 SD-VBS/common/toolbox/lagrcv/calcSobelPyrMex.mexa64 create mode 100755 SD-VBS/common/toolbox/lagrcv/calcSobelPyrMex.mexglx create mode 100755 SD-VBS/common/toolbox/lagrcv/calcSubsampleAvgMex.cc create mode 100755 SD-VBS/common/toolbox/lagrcv/calcSubsampleAvgMex.mexa64 create mode 100755 SD-VBS/common/toolbox/lagrcv/calcSubsampleAvgMex.mexglx create mode 100755 SD-VBS/common/toolbox/lagrcv/calcTextureMex.cc create mode 100755 SD-VBS/common/toolbox/lagrcv/calcTextureMex.mexa64 create mode 100755 SD-VBS/common/toolbox/lagrcv/calcTextureMex.mexglx create mode 100755 SD-VBS/common/toolbox/lagrcv/calcTexturePyrMex.cc create mode 100755 SD-VBS/common/toolbox/lagrcv/calcTexturePyrMex.mexa64 create mode 100755 SD-VBS/common/toolbox/lagrcv/calcTexturePyrMex.mexglx create mode 100755 SD-VBS/common/toolbox/lagrcv/dummyMex.cc create mode 100755 SD-VBS/common/toolbox/lagrcv/dummyMex.mexa64 create mode 100755 SD-VBS/common/toolbox/lagrcv/dummyMex.mexglx create mode 100755 SD-VBS/common/toolbox/lagrcv/findCornerSubPix.cc create mode 100755 SD-VBS/common/toolbox/lagrcv/goodFeaturesToTrack.cc create mode 100755 SD-VBS/common/toolbox/lagrcv/goodFeaturesToTrack.mexglx create mode 100755 SD-VBS/common/toolbox/lagrcv/lagrcv.cpp create mode 100755 SD-VBS/common/toolbox/lagrcv/lagrcv.h create mode 100755 SD-VBS/common/toolbox/lagrcv/liblagrcv.a create mode 100755 SD-VBS/common/toolbox/lagrcv/lk_flow.cc create mode 100755 SD-VBS/common/toolbox/lagrcv/lk_flow.mexglx create mode 100755 SD-VBS/common/toolbox/lagrcv/test.cc create mode 100755 SD-VBS/common/toolbox/lagrcv/test/getPyramid.m create mode 100755 SD-VBS/common/toolbox/lagrcv/test/img0.ppm create mode 100755 SD-VBS/common/toolbox/lagrcv/test/img1.ppm create mode 100755 SD-VBS/common/toolbox/lagrcv/test/pathdef.m create mode 100755 SD-VBS/common/toolbox/lagrcv/test/test_lk.m create mode 100755 SD-VBS/common/toolbox/lagrcv/test/test_lk_disp.m create mode 100755 SD-VBS/common/toolbox/lagrcv/test/test_lk_opencv.m create mode 100755 SD-VBS/common/toolbox/mex_template.c create mode 100755 SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/Distor2Calib.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/Rectangle2Square.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/UnWarpPlane.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/add_suppress.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/analyse_error.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/apply_distortion.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/calib_gui.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/check_active_images.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/check_convergence.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/check_directory.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/check_extracted_images.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/clear_windows.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/clearwin.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/click_calib.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/click_ima_calib.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/click_ima_calib3D.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/comp_distortion.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/comp_distortion2.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/comp_distortion_oulu.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/comp_error_calib.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/compute_collineation.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/compute_extrinsic.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/compute_extrinsic_init.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/compute_extrinsic_refine.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/compute_homography.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/cornerfinder.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/count_squares.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/data_calib.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/error_analysis.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/export_calib_data.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/ext_calib.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/extract_grid.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/extract_parameters.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/extract_parameters3D.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/extrinsic_computation.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/fixallvariables.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/fixvariable.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/ginput3.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/go_calib_optim.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/go_calib_optim_iter.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/ima_read_calib.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/init_intrinsic_param.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/is3D.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/loading_calib.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/loadinr.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/loadpgm.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/loadppm.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/mean_std_robust.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/mosaic.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/normalize.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/pgmread.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/project2_oulu.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/project_points.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/project_points2.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/projectedGrid.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/projector_calib.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/readras.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/recomp_corner_calib.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/rect.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/reproject_calib.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/rigid_motion.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/rodrigues.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/rotation.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/run_error_analysis.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/saveinr.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/savepgm.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/saveppm.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/saving_calib.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/script_fit_distortion.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/startup.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/undistort_image.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/willson_convert.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/willson_read.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/writeras.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/affine/README create mode 100755 SD-VBS/common/toolbox/toolbox_basic/affine/carve_it.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/affine/compute_AD.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/affine/compute_AD_disp.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/affine/compute_J.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/affine/find_AD.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/affine/find_D.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/affine/find_center.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/affine/gen_feature_s.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/affine/grad.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/affine/hemisphere_s.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/affine/im.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/affine/iter_AD.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/affine/m_interp4.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/affine/norm_inten.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/affine/pan.0.pgm create mode 100755 SD-VBS/common/toolbox/toolbox_basic/affine/pan.1.pgm create mode 100755 SD-VBS/common/toolbox/toolbox_basic/affine/readpgm.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/affine/simulation.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/affine/sports1_11_28.jpeg create mode 100755 SD-VBS/common/toolbox/toolbox_basic/affine/test_affine.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/affinityic.c create mode 100755 SD-VBS/common/toolbox/toolbox_basic/calib/TOOLBOX_calib.tar create mode 100755 SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/Distor2Calib.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/Multi_Calib_oulu.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/Rectangle2Square.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/UnWarpPlane.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/add_suppress.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/analyse_error.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/calib.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/calib3D_gui.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/calib_gui.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/check_active_images.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/check_convergence.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/check_planarity.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/click_calib.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/click_calib3D.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/click_ima_calib.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/click_ima_calib3D.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/comp_distortion.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/comp_distortion2.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/comp_distortion_oulu.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/comp_error_calib.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/compute_collineation.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/compute_extrinsic.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/compute_extrinsic_init.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/compute_extrinsic_refine.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/compute_homography.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/convert_oulu.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/cornerfinder.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/count_squares.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/data_calib.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/error_analysis.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/ext_calib.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/extract_grid.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/extract_parameters.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/extract_parameters3D.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/extrinsic_computation.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/ginput3.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/go_calib_optim.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/go_calib_optim3D.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/go_calib_optim_cont.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/go_calib_optim_iter.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/graphout_calib.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/graphout_calib3D.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/ima_read_calib.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/init_calib_param.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/init_intrinsic_param.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/is3D.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/loading_calib.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/loadinr.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/loadpgm.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/loadppm.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/mean_std_robust.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/multi_error_oulu.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/normalize.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/pgmread.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/project2_oulu.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/project_points.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/projectedGrid.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/readras.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/recomp_corner_calib.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/rect.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/reproject_calib.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/rigid_motion.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/rodrigues.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/rotation.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/run_error_analysis.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/saveinr.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/savepgm.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/saveppm.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/saving_calib.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/script_fit_distortion.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/select_sol_no_center.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/select_sol_no_center3D.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/select_sol_with_center.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/select_sol_with_center3D.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/startup.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/test_3d.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/undistort_image.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/writeras.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj2/TOOLBOX_calib.tar create mode 100755 SD-VBS/common/toolbox/toolbox_basic/common/Ncut_IC.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/common/Ncut_IC_m.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/common/Ncut_IC_m2.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/common/affinityic.c create mode 100755 SD-VBS/common/toolbox/toolbox_basic/common/affinityic.mexa64 create mode 100755 SD-VBS/common/toolbox/toolbox_basic/common/affinityic.mexglx create mode 100755 SD-VBS/common/toolbox/toolbox_basic/common/anisodiff.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/common/bin.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/common/cimgnbmap.c create mode 100755 SD-VBS/common/toolbox/toolbox_basic/common/cimgnbmap.mexa64 create mode 100755 SD-VBS/common/toolbox/toolbox_basic/common/cimgnbmap.mexglx create mode 100755 SD-VBS/common/toolbox/toolbox_basic/common/density.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/common/find_edge.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/common/grad.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/common/make_filterbank_even2.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/common/make_filterbank_odd2.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/common/max_supress2.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/common/mgrad.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/common/mpgread.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/common/mpgread.mexlx create mode 100755 SD-VBS/common/toolbox/toolbox_basic/common/mpgwrite.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/common/mpgwrite.mexlx create mode 100755 SD-VBS/common/toolbox/toolbox_basic/common/ncut.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/common/ncut_b.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/common/ncut_bb.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/common/ncut_e.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/common/ncut_neg.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/common/ncut_sparse.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/common/ncut_tmp.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/common/ncutd.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/common/nonmaxsup.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/common/pair_dist.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/common/quadedgep.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/common/readpcm.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/common/readpdm.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/common/readpfm.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/common/renormalize.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/common/show_edge.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/common/spmtimesd.c create mode 100755 SD-VBS/common/toolbox/toolbox_basic/common/spmtimesd.mexa64 create mode 100755 SD-VBS/common/toolbox/toolbox_basic/common/spmtimesd.mexglx create mode 100755 SD-VBS/common/toolbox/toolbox_basic/common/tmp.tex create mode 100755 SD-VBS/common/toolbox/toolbox_basic/common/vmquant.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/common/vmquantc.mexhp7 create mode 100755 SD-VBS/common/toolbox/toolbox_basic/common/vmquantc.mexlx create mode 100755 SD-VBS/common/toolbox/toolbox_basic/common/vmquantc.mexsol create mode 100755 SD-VBS/common/toolbox/toolbox_basic/common/writepdm.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/common/writepfm.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/disp/disp_image.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/disp/draw_box.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/disp/draw_box2.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/disp/im.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/disp/ims.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/disp/montage2.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/disp/showmask.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/disp/showmaskb.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/fact/construct_w.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/fact/construct_w2.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/fact/factor.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/fact/factor_test.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/fact/factor_test2.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/fact/factorizaion.tar create mode 100755 SD-VBS/common/toolbox/toolbox_basic/fact/findG.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/fact/findg1.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/fact/findg2.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/fact/hotel.mat create mode 100755 SD-VBS/common/toolbox/toolbox_basic/fact/show_3dpoints.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/fact/show_S.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/fact/show_t.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/fact/show_t3.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/fact/zt.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/filter/91048.jpg create mode 100755 SD-VBS/common/toolbox/toolbox_basic/filter/bar2d.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/filter/barrot.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/filter/bars.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/filter/clip_image.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/filter/compute_J_simple.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/filter/compute_angle.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/filter/compute_filter_fft.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/filter/compute_g2.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/filter/compute_h2.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/filter/compute_ofilter_fft.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/filter/dgauss.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/filter/dog1.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/filter/dog2.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/filter/doog1.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/filter/doog2.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/filter/fft_filt.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/filter/fft_filt_2.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/filter/filter_bank_jshi.tar create mode 100755 SD-VBS/common/toolbox/toolbox_basic/filter/gauss.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/filter/gaussian.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/filter/get_diff2.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/filter/get_diff_free.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/filter/grad1.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/filter/grad2.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/filter/m_interp4.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/filter/make_filterbank.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/filter/make_filterbank_23.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/filter/make_filterbank_even.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/filter/make_filterbank_odd.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/filter/mdoog2.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/filter/mimrotate.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/filter/mk_odd_filter.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/filter/mkdog1.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/filter/mkdog2.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/filter/mkdoog2.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/filter/mkdoogs.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/filter/mkg.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/filter/quadpair.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/filter/smooth.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/filter/softkmean.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/filter/softmeans.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/filter/softmeans2.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/filterQuad.zip create mode 100755 SD-VBS/common/toolbox/toolbox_basic/filter_hist/1d_cut.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/filter_hist/Bfilter.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/filter_hist/BfilterS.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/filter_hist/Ncut.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/filter_hist/apply_image.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/filter_hist/back_proj.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/filter_hist/backproj_outer.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/filter_hist/backproj_outer_chank.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/filter_hist/backproj_outer_chank2.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/filter_hist/binize.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/filter_hist/binize_old.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/filter_hist/binomialfield.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/filter_hist/colize.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/filter_hist/colize_hist.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/filter_hist/colize_histnb_s.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/filter_hist/colize_histnb_sf.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/filter_hist/colize_histneighb.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/filter_hist/colize_joint_hist.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/filter_hist/colize_test.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/filter_hist/compact.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/filter_hist/compute_J.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/filter_hist/compute_Lf.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/filter_hist/compute_corr.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/filter_hist/compute_diff.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/filter_hist/compute_diff_patch.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/filter_hist/compute_diff_patch2.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/filter_hist/compute_filter.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/filter_hist/compute_filter_fft.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/filter_hist/conv_trim.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/filter_hist/corr_hist.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/filter_hist/crop_im_fil.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/filter_hist/cutoff.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/filter_hist/cutout.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/filter_hist/disp_Imask.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/filter_hist/disp_diff.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/filter_hist/disp_evresult.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/filter_hist/disp_evresult2.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/filter_hist/disp_evresulthome.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/filter_hist/disp_groups.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/filter_hist/disp_hist2d.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/filter_hist/dist_pair.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/filter_hist/dist_pair_chank.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/filter_hist/doog2.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/filter_hist/eig_decomp.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/filter_hist/eig_decomp_v5.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/filter_hist/eig_proj.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/filter_hist/eigs_decomp.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/filter_hist/euclid_dist.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/filter_hist/filter_all_files.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/filter_hist/filter_output.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/filter_hist/find_bst_cut.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/filter_hist/find_center.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/filter_hist/find_cutpoint.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/filter_hist/gen_filters.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/filter_hist/get_cumhist.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/filter_hist/get_cumhist_inten.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/filter_hist/get_hist.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/filter_hist/get_hist_inten.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/filter_hist/get_win.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/filter_hist/get_win5.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/filter_hist/grad.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/filter_hist/half_sigmoid.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/filter_hist/hist2d.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/filter_hist/hist_I_f.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/filter_hist/hist_diff.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/filter_hist/hist_f.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/filter_hist/hist_in_chank.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/filter_hist/hist_inner.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/filter_hist/histbin_fv_chank.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/filter_hist/hsv2clrs.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/filter_hist/id_cut.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/filter_hist/im.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/filter_hist/im3.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/filter_hist/im5.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/filter_hist/im_vect.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/filter_hist/imrotate.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/filter_hist/ims.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/filter_hist/imvs.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/filter_hist/is_step.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/filter_hist/ks_2d.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/filter_hist/load_result.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/filter_hist/m_interp4.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/filter_hist/make_masks.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/filter_hist/makefilter.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/filter_hist/mkf_t1.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/filter_hist/mkf_t2.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/filter_hist/mkf_test.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/filter_hist/mkg.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/filter_hist/mkgaussian.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/filter_hist/mkmulfilter.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/filter_hist/mkpoog2.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/filter_hist/mksgn.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/filter_hist/mksgn2.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/filter_hist/mreadpfm.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/filter_hist/mreadpfm2.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/filter_hist/mwis.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/filter_hist/mwis_image.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/filter_hist/myinterp.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/filter_hist/ncut_b.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/filter_hist/new_compute_J.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/filter_hist/pair_dist.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/filter_hist/pair_dist2.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/filter_hist/pair_dist_text.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/filter_hist/pair_dist_text2.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/filter_hist/pair_dist_text3.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/filter_hist/pair_dist_text4.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/filter_hist/patch_cat.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/filter_hist/pgmread.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/filter_hist/poisson.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/filter_hist/poissonfield.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/filter_hist/proj_back.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/filter_hist/proj_back_id.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/filter_hist/quant.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/filter_hist/readpdm.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/filter_hist/readpfm.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/filter_hist/readpfm_id.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/filter_hist/readpfm_idf.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/filter_hist/readpgm.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/filter_hist/readpnm.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/filter_hist/readppm.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/filter_hist/record.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/filter_hist/recursive_cut_tc.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/filter_hist/reduce_all.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/filter_hist/rotate_J.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/filter_hist/session.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/filter_hist/show_cumhist.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/filter_hist/show_hist.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/filter_hist/showsmm.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/filter_hist/showsmm_v5.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/filter_hist/sigmoid.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/filter_hist/signif.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/filter_hist/signif_N.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/filter_hist/smooth.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/filter_hist/startup.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/filter_hist/swarp.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/filter_hist/swarpback.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/filter_hist/test.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/filter_hist/test1.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/filter_hist/test2.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/filter_hist/test3.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/filter_hist/test_best_cut.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/filter_hist/test_evtex.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/filter_hist/test_evtex2.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/filter_hist/test_evtex3.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/filter_hist/test_evtex4.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/filter_hist/test_evtex5.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/filter_hist/test_motion.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/filter_hist/test_motion2.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/filter_hist/test_period.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/filter_hist/test_text.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/filter_hist/tmp.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/filter_hist/tmp1.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/filter_hist/tmp2.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/filter_hist/tmp3.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/filter_hist/true_loc.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/filter_hist/vmquant.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/filter_hist/wismm.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/filter_hist/wismm2.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/filter_hist/wismm3.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/filter_hist/write_command.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/filter_hist/write_test.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/filter_hist/writeout_feature.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/filter_hist/writepfm.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/filter_hist/writepgm.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/filter_hist/writepmm.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/filter_hist/writepnm5.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/filtersQuad/doog1.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/filtersQuad/doog2.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/filtersQuad/make_filterbank_even2.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/filtersQuad/make_filterbank_odd2.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/filtersQuad/quadedgep2.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/io/convert422.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/io/im_vd.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/io/imread2.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/io/peek_pgm_size.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/io/pgmread.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/io/ppmtojpg.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/io/read422.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/io/read422f.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/io/read_cimgs.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/io/read_ev_pgm.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/io/read_ev_pgm2.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/io/read_ev_pgm_real.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/io/read_imgs.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/io/read_pmm.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/io/read_scan.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/io/read_seg_file.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/io/readlines.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/io/readpdm3.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/io/readpdmc.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/io/readpfm.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/io/readpfm3.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/io/readpfmc.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/io/readpgm.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/io/readpgm_evinfo.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/io/readpmm.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/io/readppm.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/io/writepgm.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/io/writeppm.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/matching/pub/contrib/v5/optim/assignprob/Contents.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/matching/pub/contrib/v5/optim/assignprob/allcosts.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/matching/pub/contrib/v5/optim/assignprob/allperm.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/matching/pub/contrib/v5/optim/assignprob/condass.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/matching/pub/contrib/v5/optim/assignprob/demo.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/matching/pub/contrib/v5/optim/assignprob/hungarian.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/matching/pub/contrib/v5/optim/assignprob/test.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/pyramid/091399fbn-jets.3.jpg create mode 100755 SD-VBS/common/toolbox/toolbox_basic/pyramid/expand.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/pyramid/gauss_lowpass.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/pyramid/gen_w.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/pyramid/reduce.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/pyramid/session.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/pyramid/startup.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/remap_angle.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/spmtimesd.c create mode 100755 SD-VBS/common/toolbox/toolbox_basic/stella/afromncut.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/stella/dispimg.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/stella/firstncut.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/stella/getfnames.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/stella/getimage2.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/stella/globalenvar.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/stella/jshincut.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/stella/jshincutdefpar.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/stella/ncutcheckin.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/stella/openfigure.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/stella/showim.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/stella/showncut.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/stella/startup.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/stella/test_ncutm.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/tars/TOOLBOX_calib.tar create mode 100755 SD-VBS/common/toolbox/toolbox_basic/textons/dist2.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/textons/find_textons.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/textons/find_textons1.m create mode 100755 SD-VBS/common/toolbox/toolbox_basic/textons/kmeans2.m (limited to 'SD-VBS/common') diff --git a/SD-VBS/common/c/calcSobel_dX.c b/SD-VBS/common/c/calcSobel_dX.c new file mode 100644 index 0000000..4be5845 --- /dev/null +++ b/SD-VBS/common/c/calcSobel_dX.c @@ -0,0 +1,77 @@ +/******************************** +Author: Sravanthi Kota Venkata +********************************/ + +#include +#include +#include "sdvbs_common.h" + +F2D* calcSobel_dX(F2D* imageIn) +{ + int rows, cols; + F2D *kernel_1, *kernel_2; + float temp; + int kernelSize, startCol, endCol, halfKernel, startRow, endRow, i, j, kernelSum; + int k, kernelSum_1, kernelSum_2; + F2D *imageOut, *tempOut; + + rows = imageIn->height; + cols = imageIn->width; + + imageOut = fSetArray(rows, cols, 0); + tempOut = fSetArray(rows, cols, 0); + kernel_1 = fMallocHandle(1, 3); + kernel_2 = fMallocHandle(1, 3); + + asubsref(kernel_1,0) = 1; + asubsref(kernel_1,1) = 2; + asubsref(kernel_1,2) = 1; + + kernelSize = 3; + kernelSum_1 = 4; + + asubsref(kernel_2,0) = 1; + asubsref(kernel_2,1) = 0; + asubsref(kernel_2,2) = -1; + + kernelSum_2 = 2; + + startCol = 1; + endCol = cols - 1; + halfKernel = 1; + + startRow = 1; + endRow = rows - 1; + + for(i=startRow; iheight; + cols = imageIn->width; + + // level 1 is the base image. + + outputRows = rows; + outputCols = cols; + + imageOut = fSetArray(outputRows, outputCols, 0); + tempOut = fSetArray(outputRows, outputCols, 0); + kernel_1 = iMallocHandle(1, 3); + kernel_2 = iMallocHandle(1, 3); + + asubsref(kernel_1,0) = 1; + asubsref(kernel_1,1) = 0; + asubsref(kernel_1,2) = -1; + kernelSize = 3; + kernelSum_1 = 2.0; + + asubsref(kernel_2,0) = 1; + asubsref(kernel_2,1) = 2; + asubsref(kernel_2,2) = 1; + kernelSum_2 = 4; + + startCol = 1; + endCol = cols - 1; + halfKernel = 1; + + startRow = 1; + endRow = rows - 1; + + for(i=startRow; i // For O_CREAT and O_RDWR +#include // For sched_yield() +#include // For sem_{open, post, wait}() +#include +#include // For exit() +#include // For strlen() +#include // For mlockall() +#include // For ftruncate() +#include + +// This is only visible if _GNU_SOURCE is defined, and that define does not +// come along to places where this file is included. Address this by manually +// forcing it into the global namespace. +extern int sched_getcpu(); + +// These constants correspond to the imx6q-sabredb platform +#define LINE_SIZE 32 +#define L2_SIZE 16*2048*32 + +#if __arm__ +#include +#include +#endif + +#define LITMUS 1 +#define MC2 0 +#define MMDC_PROF 0 + +#if LITMUS +#include +#endif + +#if MMDC_PROF +#include "/media/speedy/litmus/tools/mmdc/mmdc.h" +#endif + +#if LITMUS +#define SET_UP LOAD_PARAMS SETUP_LITMUS +#else +#define SET_UP LOAD_PARAMS +#endif + +#if MMDC_PROF +#define LOAD_PARAMS LOAD_PARAMS_ITRL SETUP_MMDC +#else +#define LOAD_PARAMS LOAD_PARAMS_ITRL +#endif + +// Store state globally so that the job can be outside main() +// Arrays use float as a comprimise between overflow and size +// Paired arrays use long longs as precision is more important for those times +#ifdef PAIRED +long long *_rt_start_time; +long long *_rt_end_time; +#else +float *_rt_exec_time; +#endif +#if MMDC_PERF +float *_rt_mmdc_read; +float *_rt_mmdc_write; +#endif +long _rt_jobs_complete; +long _rt_max_jobs; +int _rt_core; +int _rt_will_output; +struct timespec _rt_start, _rt_end; + +char *_rt_run_id; +char *_rt_our_prog_name; +char *_rt_other_prog_name; +char *_rt_other_core; +#define _RT_FILENAME_LEN 64 +#define _BILLION (1000*1000*1000) +#ifdef PAIRED +char *_rt_barrier; +sem_t *_rt_first_sem, *_rt_second_sem; +int _rt_lock_id; +#endif + +static void _rt_load_params_itrl(int argc, char **argv) { +#ifdef PAIRED + if (argc != 8) { + fprintf(stderr, "Usage: %s ", argv[0]); + fprintf(stderr, " string for logging. Name of this task.\n"); + fprintf(stderr, " integer number of iterations. -1 for infinite.\n"); + fprintf(stderr, " UNUSED. Core is now auto-detected.\n"); + fprintf(stderr, " integer for logging. Core of paired task.\n"); + fprintf(stderr, " string for logging. Name of paired task.\n"); + fprintf(stderr, " string to append with .txt to yield output file name.\n"); + fprintf(stderr, " 1 to indicate this is pair member 1, otherwise pair member 2.\n"); + exit(1); + } +#else + if (argc != 6) { + fprintf(stderr, "Usage: %s \n", argv[0]); + fprintf(stderr, " string for logging. Name of this task.\n"); + fprintf(stderr, " integer number of iterations. -1 for infinite.\n"); + fprintf(stderr, " UNUSED. Core is now auto-detected.\n"); + fprintf(stderr, " string to append with .txt to yield output file name.\n"); + fprintf(stderr, " 1 to save results, 0 to discard.\n"); + exit(1); + } +#endif + _rt_our_prog_name = argv[1]; + _rt_max_jobs = atol(argv[2]); + _rt_core = sched_getcpu(); +#ifdef PAIRED + _rt_other_core = argv[4]; + _rt_other_prog_name = argv[5]; + _rt_run_id = argv[6]; + _rt_lock_id = atoi(argv[7]); + // The paired version doesn't support disabling output (legacy compatibility) + _rt_will_output = 1; +#else + _rt_other_core = "none"; + _rt_other_prog_name = "none"; + _rt_run_id = argv[4]; + _rt_will_output = atoi(argv[5]); +#endif /* PAIRED */ + if (_rt_max_jobs < 0 && _rt_will_output != 0) { + fprintf(stderr, "Infinite loops only supported when _rt_will_output is disabled!\n"); + exit(1); + } + if (strlen(_rt_run_id) + 5 > _RT_FILENAME_LEN) { + fprintf(stderr, "Run ID is too large! Keep it to less than %d characters.\n", _RT_FILENAME_LEN); + exit(1); + } +#ifdef PAIRED + _rt_start_time = calloc(_rt_max_jobs * _rt_will_output, sizeof(long long)); + _rt_end_time = calloc(_rt_max_jobs * _rt_will_output, sizeof(long long)); + if (!_rt_end_time || !_rt_start_time) { + perror("Unable to allocate buffers for execution times"); + exit(1); + } + _rt_first_sem = sem_open("/_libextra_first_sem", O_CREAT, 644, 0); + _rt_second_sem = sem_open("/_libextra_second_sem", O_CREAT, 644, 0); + if (_rt_first_sem == SEM_FAILED || _rt_second_sem == SEM_FAILED) { + perror("Error while creating semaphores"); + exit(1); + } + int barrier_file = shm_open("/_libextra_barrier", O_CREAT | O_RDWR, 644); + if (barrier_file == -1) { + perror("Error while creating shared memory for barrier synchronization"); + exit(1); + } + if (ftruncate(barrier_file, 1) == -1) { + perror("Error while setting size of shared memory for barrier synchronization"); + exit(1); + } + _rt_barrier = mmap(NULL, 1, PROT_WRITE, MAP_SHARED, barrier_file, 0); + if (_rt_barrier == MAP_FAILED) { + perror("Error while mapping shared memory for barrier synchronization"); + exit(1); + } + *_rt_barrier = 0; +#else + _rt_exec_time = calloc(_rt_max_jobs * _rt_will_output, sizeof(float)); + if (!_rt_exec_time) { + perror("Unable to allocate buffer for execution times"); + exit(1); + } +#endif /* PAIRED */ + _rt_jobs_complete = 0; + mlockall(MCL_CURRENT || MCL_FUTURE); +} +#define LOAD_PARAMS_ITRL _rt_load_params_itrl(argc, argv); + +#define SETUP_MMDC \ + _rt_mmdc_read = calloc(_rt_max_jobs * _rt_will_output, sizeof(float));\ + _rt_mmdc_write = calloc(_rt_max_jobs * _rt_will_output, sizeof(float));\ + if (!_rt_mmdc_read || !_rt_mmdc_write) {\ + perror("Unable to allocate buffer for MMDC data");\ + exit(1);\ + }\ + MMDC_PROFILE_RES_t mmdc_res;\ + memset(&mmdc_res, 0, sizeof(MMDC_PROFILE_RES_t));\ + int fd = open("/dev/mem", O_RDWR, 0);\ + if (fd < 0) {\ + perror("Unable to open /dev/mem");\ + exit(1);\ + }\ + pMMDC_t mmdc = mmap(NULL, 0x4000, PROT_READ | PROT_WRITE, MAP_SHARED, fd, MMDC_P0_IPS_BASE_ADDR);\ + if (mmdc == MAP_FAILED) {\ + perror("Unable to map MMDC address space");\ + exit(1);\ + }\ + mmdc->madpcr1 = axi_arm1;\ + msync(&(mmdc->madpcr1),4,MS_SYNC); + +#define SETUP_LITMUS \ + unsigned int wait = 0; \ + if (be_migrate_to_domain(_rt_core) < 0) { \ + perror("Unable to migrate to specified CPU"); \ + exit(1); \ + } \ + struct rt_task rt_param; \ + init_rt_task_param(&rt_param); \ + /* Supposedly the next two parameters are irrelevant when reservations are enabled, but I'm leaving them anyway... */ \ + rt_param.exec_cost = ms2ns(999); \ + rt_param.period = ms2ns(1000); \ + rt_param.priority = LITMUS_HIGHEST_PRIORITY; \ + rt_param.cls = RT_CLASS_HARD; \ + rt_param.release_policy = TASK_PERIODIC; \ + rt_param.budget_policy = NO_ENFORCEMENT; \ + rt_param.cpu = _rt_core; \ + if (set_rt_task_param(gettid(), &rt_param) < 0) { \ + perror("Unable to set real-time parameters"); \ + exit(1); \ + } \ + if (init_litmus() != 0) { \ + perror("init_litmus failed"); \ + exit(1); \ + } \ + MC2_SETUP \ + if (task_mode(LITMUS_RT_TASK) != 0) { \ + perror("Unable to become real-time task"); \ + exit(1); \ + } \ + if (wait && wait_for_ts_release() != 0) { \ + perror("Unable to wait for taskset release"); \ + exit(1); \ + } + +#if MC2 +#define MC2_SETUP \ + + set_page_color(rt_param.cpu); +#else +#define MC2_SETUP +#endif + +#define CLEANUP_LITMUS \ + if (task_mode(BACKGROUND_TASK) != 0) { \ + perror("Unable to become a real-time task"); \ + exit(1); \ + } \ + +#if __arm__ +// On ARM, manually flush the cache +#define FLUSH_CACHES \ + volatile uint8_t buffer[L2_SIZE * 4]; \ + for (uint32_t j = 0; j < 4; j++) \ + for (uint32_t i = 0; i < L2_SIZE * 4; i += LINE_SIZE) \ + buffer[i]++; +#else +// On x86 call the wbinvld instruction (it's in a kernel module due to it being ring-0) +#define FLUSH_CACHES \ + FILE *fp = fopen("/proc/wbinvd", "r");\ + if (fp == NULL) {\ + perror("Cache flush module interface cannot be opened");\ + exit(1);\ + }\ + char dummy;\ + if (fread(&dummy, 1, 1, fp) == 0) {\ + perror("Unable to access cache flush module interface");\ + exit(1);\ + }\ + fclose(fp); +#endif + +// This semaphore-based synchronization is from Sims +#define FIRST_UNLOCK \ + if (_rt_lock_id == 1) {\ + if (sem_post(_rt_second_sem) != 0) {\ + perror("Unable to unlock second semaphore");\ + exit(1);\ + }\ + } \ + else {\ + if (sem_post(_rt_first_sem) != 0) {\ + perror("Unable to unlock first semaphore");\ + exit(1);\ + }\ + } \ + +#define FIRST_LOCK \ + if (_rt_lock_id == 1) {\ + if (sem_wait(_rt_first_sem) != 0) {\ + perror("Unable to wait on first semaphore");\ + exit(1);\ + }\ + }\ + else {\ + if (sem_wait(_rt_second_sem) != 0) {\ + perror("Unable to wait on second semaphore");\ + exit(1);\ + }\ + } + +// This ensures a very low difference between pair member start times +#define BARRIER_SYNC \ + if (__sync_bool_compare_and_swap(_rt_barrier, 0, 1)) {\ + while (!__sync_bool_compare_and_swap(_rt_barrier, 0, 0)) {};\ + }\ + else {\ + __sync_bool_compare_and_swap(_rt_barrier, 1, 0);\ + } + +// Buffer timing result from a single job +static void _rt_save_job_result() { + if (_rt_jobs_complete >= _rt_max_jobs) { + fprintf(stderr, "Max jobs setting too small! Trying to record job #%ld when we only have space for %ld jobs. Exiting...\n", _rt_jobs_complete, _rt_max_jobs); + exit(1); + } + if (_rt_jobs_complete > -1 && _rt_will_output) { +#ifdef PAIRED + _rt_start_time[_rt_jobs_complete] = _rt_start.tv_sec; + _rt_start_time[_rt_jobs_complete] *= _BILLION; + _rt_start_time[_rt_jobs_complete] += _rt_start.tv_nsec; + _rt_end_time[_rt_jobs_complete] = _rt_end.tv_sec; + _rt_end_time[_rt_jobs_complete] *= _BILLION; + _rt_end_time[_rt_jobs_complete] += _rt_end.tv_nsec; +#else + _rt_exec_time[_rt_jobs_complete] = _rt_end.tv_sec - _rt_start.tv_sec; + _rt_exec_time[_rt_jobs_complete] *= _BILLION; + _rt_exec_time[_rt_jobs_complete] += _rt_end.tv_nsec - _rt_start.tv_nsec; +#endif /* PAIRED */ +#if MMDC_PROF + _rt_mmdc_read[_rt_jobs_complete] = mmdc_res.read_bytes; + _rt_mmdc_write[_rt_jobs_complete] = mmdc_res.write_bytes; +#endif + } +} + +// Save all buffered timing results to disk +static void _rt_write_to_file() { + char fileName[_RT_FILENAME_LEN]; + FILE *fp; + munlockall(); + if (!_rt_will_output) + goto out; + strcpy(fileName, _rt_run_id); + strcat(fileName, ".txt"); + fp = fopen(fileName, "a"); + if (fp == NULL) { + perror("Unable to open output file"); + exit(1); + } + // Baseline output uses a similar format with "none" for unused fields + for (int i = 0; i < _rt_jobs_complete; i++){ + fprintf(fp, "%s %s %u %s %ld", _rt_our_prog_name, _rt_other_prog_name, + _rt_core, _rt_other_core, _rt_max_jobs); +#ifdef PAIRED + // For unclear legacy reasons, paired tasks emit sec and ns separately + fprintf(fp, " %lld %lld %lld %lld", + _rt_start_time[i] / _BILLION, _rt_start_time[i] % _BILLION, + _rt_end_time[i] / _BILLION, _rt_end_time[i] % _BILLION); +#else + fprintf(fp, " %.f", _rt_exec_time[i]); +#endif /* PAIRED */ + fprintf(fp, " %s %d %.f %.f\n", _rt_run_id, i, +#if MMDC_PROF + _rt_mmdc_read[i], _rt_mmdc_write[i]); +#else + 0.0, 0.0); +#endif /* MMDC_PROF */ + } + fclose(fp); +out: +#if LITMUS + CLEANUP_LITMUS +#endif /* LITMUS */ +#ifdef PAIRED + munmap(_rt_barrier, 1); + shm_unlink("/_libextra_barrier"); + sem_unlink("/_libextra_first_sem"); + sem_unlink("/_libextra_second_sem"); + free(_rt_start_time); + free(_rt_end_time); +#else + free(_rt_exec_time); +#endif /* PAIRED */ +#if MMDC_PROF + free(_rt_mmdc_read); + free(_rt_mmdc_write); +#endif /* MMDC_PROF */ +} + +// Start a job +static void _rt_start_loop() { +#if LITMUS + if (sleep_next_period() != 0) { + perror("Unable to sleep for next period"); + } +#else + sched_yield(); +#endif /* LITMUS */ +#ifdef PAIRED + FIRST_UNLOCK + FIRST_LOCK +#endif /* PAIRED */ + FLUSH_CACHES +#ifdef PAIRED + BARRIER_SYNC +#endif /* PAIRED */ +#if MMDC_PROF + /* This disables profiling, resets the counters, clears the overflow bit, and enables profiling */ + start_mmdc_profiling(mmdc); +#endif /* MMDC_PROF */ + clock_gettime(CLOCK_MONOTONIC, &_rt_start); +} + +// Complete a job +static void _rt_stop_loop() { + clock_gettime(CLOCK_MONOTONIC, &_rt_end); +#if MMDC_PROF + /* This freezes the profiling and makes results available */ + pause_mmdc_profiling(mmdc); + get_mmdc_profiling_results(mmdc, &mmdc_res); +#endif /* MMDC_PROF */ + _rt_save_job_result(); + _rt_jobs_complete++; +} + +/****** New API ****** + * Intended structure: + * + * |int main(int argc, char **argv) { + * | SET_UP + * | ... + * | for_each_job { + * | tacleInit(); + * | tacleMain(); + * | } + * | WRITE_TO_FILE + * |} + * + * The main() function must call its parameters argc and argv for SET_UP to be + * able to read them. + * Only SET_UP necessarily has to be in main(). + * + * We use some niche C features, here's a quick explaination: + * 1. The && operator doesn't evaluate the right-hand side of the expression + * unless the left side evaluated to true. We use this to only execute + * _rt_start_loop() when the loop will actually run. + * 2. The comma operator executes the first expression and then throws away the + * result. We use this to call our void function from inside a comparison. + */ +#define for_each_job \ + for (; _rt_jobs_complete < _rt_max_jobs && (_rt_start_loop(),1); \ + _rt_stop_loop()) + +/****** Legacy API ****** + * Intended structure: + * + * |int main(int argc, char **argv) { + * | SET_UP + * | for (jobsComplete=0; jobsCompleteheight; + cols = in->width; + + //out = fMallocHandle(rows, cols); + + for(i=0; iheight; + cols = in->width; + + out = fMallocHandle(rows, cols); + + for(i=0; iheight; + cols = a->width; + + c = fMallocHandle(rows, cols); + + for(i=0; i<(rows*cols); i++) + { + asubsref(c,i) = asubsref(a,i) / b; + } + + return c; +} diff --git a/SD-VBS/common/c/fFind3.c b/SD-VBS/common/c/fFind3.c new file mode 100644 index 0000000..a783bae --- /dev/null +++ b/SD-VBS/common/c/fFind3.c @@ -0,0 +1,46 @@ +/******************************** +Author: Sravanthi Kota Venkata +********************************/ + +#include "sdvbs_common.h" + +F2D* fFind3(F2D* in) +{ + int r, k, y, x, i, j; + F2D *points; + + y = in->height; + x = in->width; + + r = 0; + for(i=0; i +#include +#include "sdvbs_common.h" + +void fFreeHandle(F2D* out) +{ + if(out != NULL) + free(out); + + return; +} + diff --git a/SD-VBS/common/c/fHorzcat.c b/SD-VBS/common/c/fHorzcat.c new file mode 100644 index 0000000..9845e7c --- /dev/null +++ b/SD-VBS/common/c/fHorzcat.c @@ -0,0 +1,40 @@ +/******************************** +Author: Sravanthi Kota Venkata +********************************/ + +#include "sdvbs_common.h" + +F2D* fHorzcat(F2D* a, F2D* b) +{ + F2D* out_, *out, *c; + int rows=0, cols=0, i, j, k, c_1, c_2, r_3, c_3; + int r_1; + + r_1 = a->height; + c_1 = a->width; + cols += c_1; + c_2 = b->width; + cols += c_2; + rows = r_1; + + out = fMallocHandle(rows, cols); + + for(i=0; i +#include +#include "sdvbs_common.h" + +F2D* fMallocHandle(int rows, int cols) +{ + int i, j; + F2D* out; + + out = (F2D*)malloc(sizeof(F2D) + sizeof(float)*rows*cols); + out->height = rows; + out->width = cols; + return out; +} diff --git a/SD-VBS/common/c/fMdivide.c b/SD-VBS/common/c/fMdivide.c new file mode 100644 index 0000000..671e7d1 --- /dev/null +++ b/SD-VBS/common/c/fMdivide.c @@ -0,0 +1,27 @@ +/******************************** +Author: Sravanthi Kota Venkata +********************************/ + +#include "sdvbs_common.h" + +F2D* fMdivide(F2D* a, F2D* b) +{ + F2D *c; + int i, j, rows, cols; + + rows = a->height; + cols = a->width; + + if(rows != b->height || cols != b->width) + { + printf("fMDivide Mismatch = \nrows: %d\t%d\ncols: %d\t%d\n", rows, b->height, cols, b->width); + return NULL; + } + + c = fMallocHandle(rows, cols); + + for(i=0; i<(rows*cols); i++) + asubsref(c,i) = asubsref(a,i) / asubsref(b,i); + + return c; +} diff --git a/SD-VBS/common/c/fMinus.c b/SD-VBS/common/c/fMinus.c new file mode 100644 index 0000000..6b4954e --- /dev/null +++ b/SD-VBS/common/c/fMinus.c @@ -0,0 +1,21 @@ +/******************************** +Author: Sravanthi Kota Venkata +********************************/ + +#include "sdvbs_common.h" + +F2D* fMinus(F2D* a, F2D* b) +{ + F2D *c; + int i, j, rows, cols; + + rows = a->height; + cols = a->width; + + c = fMallocHandle(rows, cols); + + for(i=0; i<(rows*cols); i++) + asubsref(c,i) = asubsref(a,i) - asubsref(b,i); + + return c; +} diff --git a/SD-VBS/common/c/fMtimes.c b/SD-VBS/common/c/fMtimes.c new file mode 100644 index 0000000..c765d2f --- /dev/null +++ b/SD-VBS/common/c/fMtimes.c @@ -0,0 +1,38 @@ +/******************************** +Author: Sravanthi Kota Venkata +********************************/ + +#include "sdvbs_common.h" + +F2D* fMtimes(F2D* a, F2D* b) +{ + F2D *out; + int m, p, p1, n, i, j, k; + float temp; + + m = a->height; + p = a->width; + + p1 = b->height; + n = b->width; + + out = fMallocHandle(m,n); + + for(i=0; iheight; + cols = a->width; + + c = fMallocHandle(rows, cols); + + for(i=0; i<(rows*cols); i++) { + asubsref(c,i) = asubsref(a,i) + asubsref(b,i); + } + return c; +} diff --git a/SD-VBS/common/c/fResetArray.c b/SD-VBS/common/c/fResetArray.c new file mode 100644 index 0000000..23a853a --- /dev/null +++ b/SD-VBS/common/c/fResetArray.c @@ -0,0 +1,19 @@ +/******************************** +Author: Sravanthi Kota Venkata +********************************/ + +#include +#include +#include "sdvbs_common.h" + +void fResetArray(F2D *out, int rows, int cols, float val) +{ + int i, j; + + for(i=0; i +#include +#include "sdvbs_common.h" + +F2D* fResetHandle(F2D* out, int rows, int cols) +{ + int i, j; + //F2D* out; + + //out = (F2D*)malloc(sizeof(F2D) + sizeof(float)*rows*cols); + out->height = rows; + out->width = cols; + //printf("fmalloc happened\n"); + return out; +} diff --git a/SD-VBS/common/c/fReshape.c b/SD-VBS/common/c/fReshape.c new file mode 100644 index 0000000..a078826 --- /dev/null +++ b/SD-VBS/common/c/fReshape.c @@ -0,0 +1,27 @@ +/******************************** +Author: Sravanthi Kota Venkata +********************************/ + +#include "sdvbs_common.h" + +F2D* fReshape(F2D* in, int rows, int cols) +{ + F2D *out; + int i, j, k; + int r, c; + + r = in->height; + c = in->width; + + out = fMallocHandle(rows, cols); + + k = 0; + for(i=0; iheight; + cols = input->width; + + in = fCopy(input, in); + //ind = iMallocHandle(rows,cols); + + for(i=0; iheight; + c1 = in1->width; + + buffer = (float*)malloc(sizeof(float)*r1*c1); + + sprintf(file, "%s", path); + fd = fopen(file, "r"); + + if(fd == NULL) + { + printf("Error: Expected file not opened %s\n", file); + return -1; + } + + while(!feof(fd)) + { + fscanf(fd, "%f", &buffer[count]); + count++; + } + count--; + + if(count != (r1*c1)) + { + printf("Checking error: dimensions mismatch. Expected = %d, Observed = %d \n", count, (r1*c1)); + return -1; + } + + for(i=0; itol || (buffer[i]-inVal)>tol ) + { + printf("Mismatch %d: (%f, %f)\n", i, buffer[i], inVal); + return -1; + } + } + + fclose(fd); + printf("Verification\t\t- Successful\n"); + free(buffer); + return ret; +} + + diff --git a/SD-VBS/common/c/fSetArray.c b/SD-VBS/common/c/fSetArray.c new file mode 100644 index 0000000..cd8269b --- /dev/null +++ b/SD-VBS/common/c/fSetArray.c @@ -0,0 +1,22 @@ +/******************************** +Author: Sravanthi Kota Venkata +********************************/ + +#include +#include +#include "sdvbs_common.h" + +F2D* fSetArray(int rows, int cols, float val) +{ + int i, j; + F2D *out; + out = fMallocHandle(rows, cols); + + for(i=0; iheight; + cols = in->width; + + sorted = fDeepCopy(in); + + for(k=0; kheight; + cols = input->width; + + in = fDeepCopy(input); + ind = iMallocHandle(rows,cols); + + for(i=0; iheight; + cols = inMat->width; + + if(cols == 1 || rows == 1) + Rcols = 1; + else + Rcols = cols; + + outMat = fSetArray(1,Rcols,0); + + if( cols == 1) + { + temp = 0; + for( j=0; jheight; + cols = inMat->width; + + if(dir == 1) + { + newRow = 1; + newCols = cols; + } + else + { + newRow = rows; + newCols = 1; + } + + outMat = fSetArray(newRow,newCols,0); + + if(dir == 1) + { + for (i=0; iheight; + cols = a->width; + + c = fMallocHandle(rows, cols); + + for(i=0; i<(rows*cols); i++) + asubsref(c,i) = asubsref(a,i) * asubsref(b,i); + + return c; +} diff --git a/SD-VBS/common/c/fTranspose.c b/SD-VBS/common/c/fTranspose.c new file mode 100644 index 0000000..9611be2 --- /dev/null +++ b/SD-VBS/common/c/fTranspose.c @@ -0,0 +1,27 @@ +/******************************** +Author: Sravanthi Kota Venkata +********************************/ + +#include "sdvbs_common.h" + +F2D* fTranspose(F2D* a) +{ + F2D *out; + int m, p, p1, n, i, j, k; + float temp; + + m = a->height; + n = a->width; + + out = fMallocHandle(n, m); + k = 0; + for(i=0; i +#include +#include "sdvbs_common.h" + +void fWriteMatrix(F2D* input, char* inpath) +{ + FILE* fp; + char im[100]; + int rows,cols, i, j; + + sprintf(im, "%s/expected_C.txt", inpath); + fp = fopen(im, "w"); + + rows = input->height; + cols = input->width; + + for(i=0; iheight; + na = a->width; + + mb = b->height; + nb = b->width; + + ci = ma; + cj = na; + + c = fSetArray(ci, cj, 0); + + r_index = mb/2; + c_index = nb/2; + + for(i=0; i=0 && ri < ma && ci >= 0 && ci < na) + subsref(c,i,j) += subsref(a,ri,ci) * subsref(b,mm,nn); + } + } + } + } + + return c; +} diff --git a/SD-VBS/common/c/ffConv2_dY.c b/SD-VBS/common/c/ffConv2_dY.c new file mode 100644 index 0000000..e480eaa --- /dev/null +++ b/SD-VBS/common/c/ffConv2_dY.c @@ -0,0 +1,52 @@ +/******************************** +Author: Sravanthi Kota Venkata +********************************/ + +#include "sdvbs_common.h" + +F2D* ffConv2_dY(F2D* a, F2D* b) +{ + F2D *c, *out; + int ma, na, mb, nb, ci, cj, i, j, m, n; + int r_index, c_index; + + ma = a->height; + na = a->width; + + mb = b->height; + nb = b->width; + + r_index = ceil((mb + 1.0)/2.0); + c_index = ceil((nb + 1.0)/2.0); + + ci = ma+mb-1; + cj = na+nb-1; + + c = fSetArray(ci, cj, 0); + + for(i=0; i=0 && (j-n)>=0 && (i-m)height; + cols = a->width; + + c = fMallocHandle(rows, cols); + + for(i=0; i<(rows*cols); i++) + asubsref(c,i) = asubsref(a,i) / asubsref(b,i); + + return c; +} diff --git a/SD-VBS/common/c/ffTimes.c b/SD-VBS/common/c/ffTimes.c new file mode 100644 index 0000000..8ef84b8 --- /dev/null +++ b/SD-VBS/common/c/ffTimes.c @@ -0,0 +1,21 @@ +/******************************** +Author: Sravanthi Kota Venkata +********************************/ + +#include "sdvbs_common.h" + +F2D* ffTimes(F2D* a, float b) +{ + F2D *c; + int i, j, rows, cols; + + rows = a->height; + cols = a->width; + + c = fMallocHandle(rows, cols); + + for(i=0; i<(rows*cols); i++) + asubsref(c,i) = asubsref(a,i) * b; + + return c; +} diff --git a/SD-VBS/common/c/ffVertcat.c b/SD-VBS/common/c/ffVertcat.c new file mode 100644 index 0000000..00fa74b --- /dev/null +++ b/SD-VBS/common/c/ffVertcat.c @@ -0,0 +1,36 @@ +/******************************** +Author: Sravanthi Kota Venkata +********************************/ + +#include "sdvbs_common.h" + +F2D* ffVertcat(F2D* matrix1, F2D* matrix2) +{ + F2D *outMatrix; + int row1, col1, row2, col2, i, j, k; + + row1 = matrix1->height; + col1 = matrix1->width; + + row2 = matrix2->height; + col2 = matrix2->width; + + outMatrix = fMallocHandle(row1+row2, col1); + + for( i=0; iheight; + na = a->width; + + mb = b->height; + nb = b->width; + + r_index = ceil((mb + 1.0)/2.0); + c_index = ceil((nb + 1.0)/2.0); + + ci = ma+mb-1; + cj = na+nb-1; + + c = fSetArray(ci, cj, 0); + + for(i=0; i=0 && (j-n)>=0 && (i-m)height; + na = a->width; + + mb = b->height; + nb = b->width; + + r_index = ceil((mb + 1.0)/2.0); + c_index = ceil((nb + 1.0)/2.0); + + ci = ma+mb-1; + cj = na+nb-1; + + c = fSetArray(ci, cj, 0); + + for(i=0; i=0 && (j-n)>=0 && (i-m)height; + cols = in->width; + + //out = fMallocHandle(rows, cols); + + for(i=0; iheight; + cols = in->width; + + out = fMallocHandle(rows, cols); + + for(i=0; iwidth; + cols += c_1; + + c_2 = b->width; + cols += c_2; + + r_3 = c->height; + c_3 = c->width; + cols += c_3; + rows = r_3; + + out = fMallocHandle(rows, cols); + + for(i=0; iwidth != in2 -> width || in1->height != in2->height) return 0; + for(int i = 0; i < in1->width;i++){ + for(int j = 0; j < in1->height;j++){ + if(subsref(in1,i,j) != subsref(in2,i,j)) return 0; + } + } + return 1; + +} + + diff --git a/SD-VBS/common/c/iDeepCopy.c b/SD-VBS/common/c/iDeepCopy.c new file mode 100644 index 0000000..8d56680 --- /dev/null +++ b/SD-VBS/common/c/iDeepCopy.c @@ -0,0 +1,23 @@ +/******************************** +Author: Sravanthi Kota Venkata +********************************/ + +#include "sdvbs_common.h" + +I2D* iDeepCopy(I2D* in) +{ + int i, j; + I2D* out; + int rows, cols; + + rows = in->height; + cols = in->width; + + out = iMallocHandle(rows, cols); + + for(i=0; i +#include +#include "sdvbs_common.h" + +void iFreeHandle(I2D* out) +{ + if(out != NULL) + free(out); + + return; +} + diff --git a/SD-VBS/common/c/iHorzcat.c b/SD-VBS/common/c/iHorzcat.c new file mode 100644 index 0000000..ac1c4ea --- /dev/null +++ b/SD-VBS/common/c/iHorzcat.c @@ -0,0 +1,41 @@ +/******************************** +Author: Sravanthi Kota Venkata +********************************/ + +#include "sdvbs_common.h" + +I2D* iHorzcat(I2D* a, I2D* b) +{ + I2D *out, *c; + int rows=0, cols=0, i, j, k, c_1, c_2, r_3, c_3; + int r_1; + + r_1 = a->height; + c_1 = a->width; + cols += c_1; + + c_2 = b->width; + cols += c_2; + rows = r_1; + + out = iMallocHandle(rows, cols); + + for(i=0; i +#include +#include "sdvbs_common.h" + +I2D* iMallocHandle(int rows, int cols) +{ + int i, j; + I2D* out; + + out = (I2D*)malloc(sizeof(I2D) + sizeof(int)*rows*cols); + out->height = rows; + out->width = cols; + //printf("imalloc happened\n"); + return out; +} + diff --git a/SD-VBS/common/c/iMinus.c b/SD-VBS/common/c/iMinus.c new file mode 100644 index 0000000..a0ed908 --- /dev/null +++ b/SD-VBS/common/c/iMinus.c @@ -0,0 +1,21 @@ +/******************************** +Author: Sravanthi Kota Venkata +********************************/ + +#include "sdvbs_common.h" + +I2D* iMinus(I2D* a, I2D* b) +{ + I2D *c; + int i, j, rows, cols; + + rows = a->height; + cols = a->width; + + c = iMallocHandle(rows, cols); + + for(i=0; i<(rows*cols); i++) + asubsref(c,i) = asubsref(a,i) - asubsref(b,i); + + return c; +} diff --git a/SD-VBS/common/c/iResetArray.c b/SD-VBS/common/c/iResetArray.c new file mode 100644 index 0000000..3659d15 --- /dev/null +++ b/SD-VBS/common/c/iResetArray.c @@ -0,0 +1,22 @@ +/******************************** +Author: Sravanthi Kota Venkata +********************************/ + +#include +#include +#include "sdvbs_common.h" + +void iResetArray(I2D* out, int rows, int cols, int val) +{ + int i, j; + //I2D *out; + //out = iMallocHandle(rows, cols); + + for(i=0; iheight; + c = in->width; + + out = iMallocHandle(rows, cols); + + k = 0; + for(i=0; i +#include +#include "sdvbs_common.h" + +I2D* iSetArray(int rows, int cols, int val) +{ + int i, j; + I2D *out; + out = iMallocHandle(rows, cols); + + for(i=0; iheight; + cols = in->width; + + sorted = iDeepCopy(in); + + for(k=0; kheight; + cols = in->width; + + sorted = iDeepCopy(in); + ind = iMallocHandle(rows, cols); + + for(i=0; iheight; + cols = a->width; + + c = iMallocHandle(rows, cols); + + for(i=0; i<(rows*cols); i++) + asubsref(c,i) = asubsref(a,i) * asubsref(b,i); + + return c; +} + diff --git a/SD-VBS/common/c/iTranspose.c b/SD-VBS/common/c/iTranspose.c new file mode 100644 index 0000000..79b65d2 --- /dev/null +++ b/SD-VBS/common/c/iTranspose.c @@ -0,0 +1,26 @@ +/******************************** +Author: Sravanthi Kota Venkata +********************************/ + +#include "sdvbs_common.h" + +I2D* iTranspose(I2D* a) +{ + I2D *out; + int m, p, p1, n, i, j, k; + int temp; + + m = a->height; + n = a->width; + + out = iMallocHandle(n, m); + k = 0; + for(i=0; iheight; + col1 = matrix1->width; + + row2 = matrix2->height; + col2 = matrix2->width; + + outMatrix = iMallocHandle(row1+row2, col1); + + for( i=0; i +#include "sdvbs_common.h" + +I2D* ifDeepCopy(F2D* in) +{ + int i, j; + I2D *out; + int rows, cols; + + rows = in->height; + cols = in->width; + + out = iMallocHandle(rows, cols); + + for(i=0; iheight; + p = a->width; + + p1 = b->height; + n = b->width; + + out = fMallocHandle(m,n); + + for(i=0; iheight; + na = a->width; + + mb = b->height; + nb = b->width; + + r_index = ceil((mb + 1.0)/2.0); + c_index = ceil((nb + 1.0)/2.0); + + ci = ma+mb-1; + cj = na+nb-1; + + c = iSetArray(ci, cj, 0); + + for(i=0; i=0 && (j-n)>=0 && (i-m)height; + cols = imageIn->width; + + imageOut = fSetArray(rows, cols, 0); + tempOut = fSetArray(rows, cols, 0); + kernel = iMallocHandle(1, 5); + + asubsref(kernel,0) = 1; + asubsref(kernel,1) = 4; + asubsref(kernel,2) = 6; + asubsref(kernel,3) = 4; + asubsref(kernel,4) = 1; + kernelSize = 5; + kernelSum = 16; + + startCol = 2; + endCol = cols - 2; + halfKernel = 2; + + startRow = 2; + endRow = rows - 2; + + for(i=startRow; iheight; + cols = imageIn->width; + + fResetArray(imageOut, rows, cols, 0); + fResetArray(tempOut, rows, cols, 0); + //kernel = iMallocHandle(1, 5); + + asubsref(kernel,0) = 1; + asubsref(kernel,1) = 4; + asubsref(kernel,2) = 6; + asubsref(kernel,3) = 4; + asubsref(kernel,4) = 1; + kernelSize = 5; + kernelSum = 16; + + startCol = 2; + endCol = cols - 2; + halfKernel = 2; + + startRow = 2; + endRow = rows - 2; + + for(i=startRow; iheight; + cols = imageIn->width; + + // level 1 is the base image. + + outputRows = floor((rows+1)/2); + outputCols = floor((cols+1)/2); + + temp = fSetArray(rows, outputCols, 0); + imageOut = fSetArray(outputRows, outputCols, 0); + kernel = iMallocHandle(1, 5); + + asubsref(kernel,0) = 1; + asubsref(kernel,1) = 4; + asubsref(kernel,2) = 6; + asubsref(kernel,3) = 4; + asubsref(kernel,4) = 1; + kernelSize = 5; + kernelSum = 16; + + startCol = 2; + endCol = cols - 2; + halfKernel = 2; + + startRow = 2; + endRow = rows - 2; + + for(i=startRow; i +#include +#include "sdvbs_common.h" + +I2D* isMinus(I2D* a, int b) +{ + I2D *c; + int i, j, rows, cols; + + rows = a->height; + cols = a->width; + + c = iMallocHandle(rows, cols); + + for(i=0; i<(rows*cols); i++) + asubsref(c,i) = asubsref(a,i) - b; + + return c; +} diff --git a/SD-VBS/common/c/isPlus.c b/SD-VBS/common/c/isPlus.c new file mode 100644 index 0000000..9c7438f --- /dev/null +++ b/SD-VBS/common/c/isPlus.c @@ -0,0 +1,22 @@ +/******************************** +Author: Sravanthi Kota Venkata +********************************/ + +#include "sdvbs_common.h" + +I2D* isPlus(I2D* a, int b) +{ + I2D *c; + int i, j, rows, cols; + + rows = a->height; + cols = a->width; + + c = iMallocHandle(rows, cols); + + for(i=0; i<(rows*cols); i++) + asubsref(c,i) = asubsref(a,i) + b; + + return c; +} + diff --git a/SD-VBS/common/c/photonEndTiming.c b/SD-VBS/common/c/photonEndTiming.c new file mode 100644 index 0000000..b15c4de --- /dev/null +++ b/SD-VBS/common/c/photonEndTiming.c @@ -0,0 +1,22 @@ +/******************************** +Author: Sravanthi Kota Venkata +********************************/ + +/** C File **/ +#include +#include +#include +#include +#include +#include "timingUtils.h" +#include "sdvbs_common.h" + +unsigned int * photonEndTiming() +{ + static unsigned int *array; + array = (unsigned int*)malloc(sizeof(unsigned int)*2); + + magic_timing_begin(array[0], array[1]); + return array; +} + diff --git a/SD-VBS/common/c/photonPrintTiming.c b/SD-VBS/common/c/photonPrintTiming.c new file mode 100644 index 0000000..06df530 --- /dev/null +++ b/SD-VBS/common/c/photonPrintTiming.c @@ -0,0 +1,22 @@ +/******************************** +Author: Sravanthi Kota Venkata +********************************/ + +/** C File **/ +#include +#include +#include +#include +#include +#include "timingUtils.h" +#include "sdvbs_common.h" + +void photonPrintTiming(unsigned int * elapsed) +{ + if(elapsed[1] == 0) + printf("Cycles elapsed\t\t- %u\n\n", elapsed[0]); + else + printf("Cycles elapsed\t\t- %u%u\n\n", elapsed[1], elapsed[0]); +} + +/** End of C Code **/ diff --git a/SD-VBS/common/c/photonReportTiming.c b/SD-VBS/common/c/photonReportTiming.c new file mode 100644 index 0000000..c41d103 --- /dev/null +++ b/SD-VBS/common/c/photonReportTiming.c @@ -0,0 +1,28 @@ +/******************************** +Author: Sravanthi Kota Venkata +********************************/ + +/** C File **/ +#include +#include +#include +#include +#include +#include "timingUtils.h" +#include "sdvbs_common.h" + +unsigned int * photonReportTiming(unsigned int* startCycles,unsigned int* endCycles) +{ + + static unsigned int *elapsed; + elapsed = (unsigned int*)malloc(sizeof(unsigned int)*2); + unsigned long long start = (((unsigned long long)0x0) | startCycles[0]) << 32 | startCycles[1]; + unsigned long long end = (((unsigned long long)0x0) | endCycles[0]) << 32 | endCycles[1]; + unsigned long long diff = end - start; + elapsed[0] = (unsigned int)(diff >> 32); + elapsed[1] = (unsigned int)(diff & 0xffffffff); + return elapsed; + +} + +/** End of C Code **/ diff --git a/SD-VBS/common/c/photonStartTiming.c b/SD-VBS/common/c/photonStartTiming.c new file mode 100644 index 0000000..0d0b2b1 --- /dev/null +++ b/SD-VBS/common/c/photonStartTiming.c @@ -0,0 +1,23 @@ +/******************************** +Author: Sravanthi Kota Venkata +********************************/ + +/** C File **/ +#include +#include +#include +#include +#include +#include "timingUtils.h" +#include "sdvbs_common.h" + +unsigned int* photonStartTiming() +{ + static unsigned int *array; + + array = (unsigned int*)malloc(sizeof(unsigned int)*2); + magic_timing_begin(array[0], array[1]); + return array; +} + +/** End of C Code **/ diff --git a/SD-VBS/common/c/randWrapper.c b/SD-VBS/common/c/randWrapper.c new file mode 100644 index 0000000..cadcc32 --- /dev/null +++ b/SD-VBS/common/c/randWrapper.c @@ -0,0 +1,30 @@ +/******************************** +Author: Sravanthi Kota Venkata +********************************/ + +#include "sdvbs_common.h" + +F2D* randWrapper(int m, int n) +{ + F2D *out; + float seed; + int i,j; + + out = fSetArray(m, n, 0); + seed = 0.9; + + for(i=0; i +F2D* randnWrapper(int m, int n) +{ + F2D *out; + float seed; + int i,j; + + out = fSetArray(m, n, 0); + seed = 0.9; + + for(i=0; i +#include +#include "sdvbs_common.h" + +I2D* readImage(const char* pathName) +{ + // Reading BMP image + char signature[2]; + int file_size; + short int reserved1; + short int reserved2; + int loc_of_bitmap; + + int size_of_infoheader; + int width; + int height; + short int number_of_planes; + short int bits_per_pixel; + + int compression_method; + int bytes_of_bitmap; + int hori_reso; + int vert_reso; + int no_of_colors; + int no_of_imp_colors; + + int nI,nJ; + int pixSize; + + unsigned char tempb,tempg,tempr,tempjunk[12]; + int ta; + I2D* srcImage; + + FILE *input; + input = fopen(pathName,"rb"); + if(input == NULL) + { + perror("File pointer error"); + return NULL; + } + else + { + //start of header information + fread(&signature,sizeof(signature),1,input); + fread(&file_size,sizeof(file_size),1,input); + fread(&reserved1,sizeof(reserved1),1,input); + fread(&reserved2,sizeof(reserved2),1,input); + fread(&loc_of_bitmap,sizeof(loc_of_bitmap),1,input); + + fread(&size_of_infoheader,sizeof(size_of_infoheader),1,input); + fread(&width,sizeof(width),1,input); // Reads the width of the image + fread(&height,sizeof(height),1,input); // Reads the height of the image + fread(&number_of_planes,sizeof(number_of_planes),1,input); + fread(&bits_per_pixel,sizeof(bits_per_pixel),1,input); + fread(&compression_method,sizeof(compression_method),1,input); + fread(&bytes_of_bitmap,sizeof(bytes_of_bitmap),1,input); + + fread(&hori_reso,sizeof(hori_reso),1,input); + fread(&vert_reso,sizeof(vert_reso),1,input); + fread(&no_of_colors,sizeof(no_of_colors),1,input); + fread(&no_of_imp_colors,sizeof(no_of_imp_colors),1,input); + //end of header information + + srcImage = iMallocHandle(height, width); + + // Conditions to check whether the BMP is interleaved and handling few exceptions + if(srcImage->height <= 0 || srcImage->width <= 0 || signature[0] != 'B' || signature[1] != 'M' || ( bits_per_pixel !=24 && bits_per_pixel !=8 ) ) + { + printf("ERROR in BMP read: The input file is not in standard BMP format"); + return NULL; + } + fseek(input,loc_of_bitmap,SEEK_SET); + + if (bits_per_pixel == 8) + { + for(nI = (height - 1); nI >= 0 ; nI--) + { + for(nJ = 0;nJ < width; nJ++) + { + fread(&tempg,sizeof(unsigned char),1,input); + subsref(srcImage,nI,nJ) = (int)tempg; + } + } + } + else if (bits_per_pixel == 24) + { + for(nI = (height - 1); nI >= 0 ; nI--) + { + for(nJ = 0;nJ < width; nJ++) + { + fread(&tempb,sizeof(unsigned char),1,input); + fread(&tempg,sizeof(unsigned char),1,input); + fread(&tempr,sizeof(unsigned char),1,input); + ta = (3*tempr + 6*tempg + tempb)/10; + ta = tempg; + subsref(srcImage,nI,nJ) = (int)ta; + } + } + } + else + { + return NULL; + } + + fclose(input); + return srcImage; + } +} diff --git a/SD-VBS/common/c/sdvbs_common.h b/SD-VBS/common/c/sdvbs_common.h new file mode 100644 index 0000000..14e28b2 --- /dev/null +++ b/SD-VBS/common/c/sdvbs_common.h @@ -0,0 +1,139 @@ +/******************************** +Author: Sravanthi Kota Venkata +********************************/ + +#ifndef _SDVBS_COMMON_ +#define _SDVBS_COMMON_ + +#include +#include +#include + +typedef struct +{ + int width; + int height; + int data[]; +}I2D; + +typedef struct +{ + int width; + int height; + unsigned int data[]; +}UI2D; + +typedef struct +{ + int width; + int height; + float data[]; +}F2D; + +#define subsref(a,i,j) a->data[(i) * a->width + (j)] +#define asubsref(a,i) a->data[i] +#define arrayref(a,i) a[i] + +/** Image read and write **/ +I2D* readImage(const char* pathName);; +F2D* readFile(unsigned char* fileName); + + +/** Memory allocation functions **/ +I2D* iMallocHandle(int rows, int cols); +F2D* fMallocHandle(int rows, int cols); +F2D* fResetHandle(F2D* out, int rows, int cols); +UI2D* uiMallocHandle(int rows, int cols); + +void iFreeHandle(I2D* out); +void fFreeHandle(F2D* out); +void uiFreeHandle(UI2D* out); + +/** Memory copy/set function **/ +I2D* iSetArray(int rows, int cols, int val); +void iResetArray(I2D* out, int rows, int cols, int val); +F2D* fSetArray(int rows, int cols, float val); +void fResetArray(F2D* out, int rows, int cols, float val); +I2D* iDeepCopy(I2D* in); +F2D* fDeepCopy(F2D* in); +F2D* fCopy(F2D* in, F2D* out); +I2D* iDeepCopyRange(I2D* in, int startRow, int numberRows, int startCol, int numberCols); +F2D* fDeepCopyRange(F2D* in, int startRow, int numberRows, int startCol, int numberCols); +F2D* fiDeepCopy(I2D* in); +void fiCopy(F2D* out, I2D* in); +I2D* ifDeepCopy(F2D* in); + + +/** Matrix operations - concatenation, reshape **/ +F2D* ffVertcat(F2D* matrix1, F2D* matrix2); +I2D* iVertcat(I2D* matrix1, I2D* matrix2); +F2D* fHorzcat(F2D* a, F2D* b); +I2D* iHorzcat(I2D* a, I2D* b); +F2D* horzcat(F2D* a, F2D* b, F2D* c); +F2D* fTranspose(F2D* a); +I2D* iTranspose(I2D* a); +F2D* fReshape(F2D* in, int rows, int cols); +I2D* iReshape(I2D* in, int rows, int cols); + + +/** Binary Operations **/ +F2D* fDivide(F2D* a, float b); +F2D* fMdivide(F2D* a, F2D* b); +F2D* ffDivide(F2D* a, F2D* b); +F2D* ffTimes(F2D* a, float b); +F2D* fTimes(F2D* a, F2D* b); +I2D* iTimes(I2D* a, I2D* b); +F2D* fMtimes(F2D* a, F2D* b); +F2D* ifMtimes(I2D* a, F2D* b); +F2D* fMinus(F2D* a, F2D* b); +I2D* iMinus(I2D* a, I2D* b); +I2D* isMinus(I2D* a, int b); +F2D* fPlus(F2D* a, F2D* b); +I2D* isPlus(I2D* a, int b); + + +/** Filtering operations **/ +F2D* calcSobel_dX(F2D* imageIn); +F2D* calcSobel_dY(F2D* imageIn); +F2D* ffConv2(F2D* a, F2D* b); +F2D* fiConv2(I2D* a, F2D* b); +F2D* ffConv2_dY(F2D* a, F2D* b); +F2D* ffiConv2(F2D* a, I2D* b); +I2D* iiConv2(I2D* a, I2D* b); + + +/** Image Transformations - resize, integration etc **/ +F2D* imageResize(F2D* imageIn); +F2D* imageBlur(I2D* imageIn); +F2D* imageReblur(I2D* imageIn, F2D* imageOut, F2D* tempOut, I2D* kernel); + + +/** Support functions **/ +F2D* fFind3(F2D* in); +F2D* fSum2(F2D* inMat, int dir); +F2D* fSum(F2D* inMat); +I2D* iSort(I2D* in, int dim); +F2D* fSort(F2D* in, int dim); +I2D* iSortIndices(I2D* in, int dim); +I2D* fSortIndices(F2D* input, int dim); +I2D* fResortIndices(F2D* input, int dim, F2D* in, I2D* ind); +F2D* randnWrapper(int m, int n); +F2D* randWrapper(int m, int n); + + +/** Checking functions **/ +int selfCheck(I2D* in1, char* path, int tol); +int fSelfCheck(F2D* in1, char* path, float tol); +void writeMatrix(I2D* input, char* inpath); +void fWriteMatrix(F2D* input, char* inpath); +int iCheck(I2D* in1, I2D* in2); + +/** Timing functions **/ +unsigned int* photonEndTiming(); +unsigned int* photonStartTiming(); +unsigned int* photonReportTiming(unsigned int* startCycles,unsigned int* endCycles); +void photonPrintTiming(unsigned int * elapsed); + + +#endif + diff --git a/SD-VBS/common/c/selfCheck.c b/SD-VBS/common/c/selfCheck.c new file mode 100644 index 0000000..e79a6a4 --- /dev/null +++ b/SD-VBS/common/c/selfCheck.c @@ -0,0 +1,65 @@ +/******************************** +Author: Sravanthi Kota Venkata +********************************/ + +#include +#include +#include +#include "sdvbs_common.h" + +int selfCheck(I2D* in1, char* path, int tol) +{ + int r1, c1, ret=1; + FILE* fd; + int count=0, *buffer, i, j; + char file[100]; + int* data = in1->data; + + r1 = in1->height; + c1 = in1->width; + + buffer = (int*)malloc(sizeof(int)*r1*c1); + + sprintf(file, "%s", path); + fd = fopen(file, "r"); + if(fd == NULL) + { + printf("Error: Expected file not opened \n"); + return -1; + } + + while(!feof(fd)) + { + fscanf(fd, "%d", &buffer[count]); + count++; + } + count--; + + if(count < (r1*c1)) + { + printf("Checking error: dimensions mismatch. Expected = %d, Observed = %d \n", count, (r1*c1)); + return -1; + } + + for(i=0; itol || (abs(buffer[i])-abs(data[i]))>tol) + { + printf("Checking error: Values mismtach at %d element\n", i); + printf("Expected value = %d, observed = %d\n", buffer[i], data[i] ); + return -1; + } + } + + fclose(fd); + free(buffer); + printf("Verification\t\t- Successful\n"); + return ret; +} + + + + + + + diff --git a/SD-VBS/common/c/timingUtils.h b/SD-VBS/common/c/timingUtils.h new file mode 100644 index 0000000..818728f --- /dev/null +++ b/SD-VBS/common/c/timingUtils.h @@ -0,0 +1,99 @@ +#ifdef GCC +#define magic_timing_begin(cycleLo, cycleHi) {\ + asm volatile( "rdtsc": "=a" (cycleLo), "=d" (cycleHi)); \ +}\ + +#define magic_timing_end(cycleLo, cycleHi) {\ + unsigned tempCycleLo, tempCycleHi; \ + asm volatile( "rdtsc": "=a" (tempCycleLo), "=d" (tempCycleHi)); \ + cycleLo = tempCycleLo-cycleLo;\ + cycleHi = tempCycleHi - cycleHi;\ +}\ + + + +#define magic_timing_report(cycleLo, cycleHi) {\ + printf("Timing report: %d %d\n", cycleLo, cycleHi); \ +}\ + + + + +#endif + +#ifdef METRO + +#define magic_timing_begin(cycleLo, cycleHi) {\ + asm volatile( "mfsr $8, CYCLE_LO\n\t" \ + "mfsr $9, CYCLE_HI\n\t" \ + "addu %0, $8, $0\n\t" \ + "addu %1, $9, $0\n\t" \ + :"=r" (cycleLo), "=r" (cycleHi) \ + : \ + :"$8", "$9"\ + );\ +} + +#define magic_timing_end(cycleLo, cycleHi) {\ + asm volatile( \ + "mfsr $8, CYCLE_LO\n\t" \ + "mfsr $9, CYCLE_HI\n\t" \ + "subu %0, $8, %0\n\t" \ + "subu %1, $9, %1\n\t" \ + :"=r" (cycleLo), "=r" (cycleHi) \ + : \ + :"$8", "$9"\ + ); \ +} + +#define magic_timing_report(cycleLo, cycleHi) {\ + asm volatile( "addu $8, %0, $0\n\t" \ + "mtsr PASS $8\n\t" \ + "mtsr PASS $9\n\t" \ + : \ + :"r" (cycleLo), "r" (cycleHi) \ + : "$8", "$9" \ + );\ +} + +//#define metro_magic_timing_report(cycleLo, cycleHi) {\ +// asm volatile( "nop\n\t");\ +//} + +#endif + +#ifdef BTL + +#include "/u/kvs/raw/rawlib/archlib/include/raw.h" + +#define magic_timing_begin(cycleLo, cycleHi) {\ + raw_magic_timing_report_begin();\ +} + +#define magic_timing_end(cycleLo, cycleHi) {\ + raw_magic_timing_report_end(); \ +} + +#define magic_timing_report(cycleLo, cycleHi) {\ + raw_magic_timing_report_print(); \ +} + + +// +//void metro_magic_timing_begin(int cycleLo, int cycleHi) +//{ +// raw_magic_timing_report_begin(); +//} +// +//void metro_magic_timing_end(int cycleLo, int cycleHi) +//{ +// raw_magic_timing_report_end(); +//} +// +//void metro_magic_timing_report(int cycleLo, int cycleHi) +//{ +// raw_magic_timing_report_print(); +// return; +//} + +#endif diff --git a/SD-VBS/common/c/uiFreeHandle.c b/SD-VBS/common/c/uiFreeHandle.c new file mode 100644 index 0000000..ce64ad9 --- /dev/null +++ b/SD-VBS/common/c/uiFreeHandle.c @@ -0,0 +1,15 @@ +/******************************** +Author: Sravanthi Kota Venkata +********************************/ + +#include +#include +#include "sdvbs_common.h" + +void uiFreeHandle(UI2D* out) +{ + free(out); + + return; +} + diff --git a/SD-VBS/common/c/uiMallocHandle.c b/SD-VBS/common/c/uiMallocHandle.c new file mode 100644 index 0000000..ee26d4c --- /dev/null +++ b/SD-VBS/common/c/uiMallocHandle.c @@ -0,0 +1,20 @@ +/******************************** +Author: Sravanthi Kota Venkata +********************************/ + +#include +#include +#include "sdvbs_common.h" + +UI2D* uiMallocHandle(int rows, int cols) +{ + int i, j; + UI2D* out; + + out = malloc(sizeof(UI2D) + sizeof(unsigned int)*rows*cols); + out->height = rows; + out->width = cols; + printf("uimalloc here\n"); + return out; +} + diff --git a/SD-VBS/common/c/uiResetArray.c b/SD-VBS/common/c/uiResetArray.c new file mode 100644 index 0000000..249e570 --- /dev/null +++ b/SD-VBS/common/c/uiResetArray.c @@ -0,0 +1,19 @@ +/******************************** +Author: Sravanthi Kota Venkata +********************************/ + +#include +#include +#include "sdvbs_common.h" + +void uiResetArray(UI2D* out, int rows, int cols, int val) +{ + int i, j; + + + for(i=0; i +#include +#include "sdvbs_common.h" + +UI2D* uiSetArray(int rows, int cols, int val) +{ + int i, j; + UI2D *out; + out = uiMallocHandle(rows, cols); + + for(i=0; i +#include +#include "sdvbs_common.h" + +void writeMatrix(I2D* input, char* inpath) +{ + FILE* fp; + char im[100]; + int rows,cols, i, j; + + sprintf(im, "%s/expected_C.txt", inpath); + fp = fopen(im, "w"); + + rows = input->height; + cols = input->width; + + for(i=0; i1 input images =. + +# Variables exported from the benchmark specific Makefiles: +# BMARK +# INPUT - sqcif/qcif/cif + +# Matlab source, data and result directory + +M_DIR=$(BMARK_DIR)/src/matlab +M_DATA=$(BMARK_DIR)/data/$(INPUT) +M_RESULT=$(BMARK_DIR)/result + +# C source, data and result directory + +C_DIR=$(BMARK_DIR)/src/c +DATA_DIR=$(BMARK_DIR)/data/$(INPUT) +C_RESULT=$(M_RESULT) + +# Source files for C and Common folders + +C_SRC := $(wildcard $(C_DIR)/*.c) +COMMON_SRC := $(wildcard $(COMMON_DIR)/*.c) + +# RULES + +EXE = +INCLUDES = -I$(COMMON_DIR) -I$(C_DIR) -I${LIBLITMUS}/include -I${LIBLITMUS}/arch/arm/include +COMPILE_C = $(CC) $(CFLAGS) $(INCLUDES) -O2 +#COMPILE_C = $(CC) $(CFLAGS) -DGENERATE_OUTPUT -lm -O2 $(INCLUDES) +COMPILE_G = $(CC) $(CFLAGS) -g -lm $(INCLUDES) +COMPILE_PG = $(COMPILE_G) -pg + +preload-run: compile + @echo preloaded timing + @echo 3 | tee /proc/sys/vm/drop_caches + @find ./ -iname "*.bmp" -exec sh -c '$(TOOL_DIR)/preload {} &' \; + @find ./ -iname "*.txt" -exec sh -c '$(TOOL_DIR)/preload {} &' \; + mkdir -p $(PRELOAD_TIMES_DIR) + @echo -e "Data set\t\t- $(INPUT)" + (time ./$(BMARK)$(EXE) $(DATA_DIR)) |& tee $(PRELOAD_TIMES_DIR)/T_$(INPUT).txt + @kill -2 `pgrep preload` + +time-run: compile + mkdir -p $(TIMES_DIR) + @echo -e "Data set\t\t- $(INPUT)" + @echo 3 | tee /proc/sys/vm/drop_caches + (time ./$(BMARK)$(EXE) $(DATA_DIR)) |& tee $(TIMES_DIR)/T_$(INPUT).txt + +c-run: compile + @echo -e "Data set\t\t- $(INPUT)" + mkdir -p $(TIMING_DIR) + @./$(BMARK)$(EXE) $(DATA_DIR) $(C_RESULT) | tee $(TIMING_DIR)/C_$(INPUT).txt + +run: compile + @echo -e "Data set\t\t- $(INPUT)" + @./$(BMARK)$(EXE) $(DATA_DIR) $(C_RESULT) + +rt-run: compile + @echo -e "Data set\t\t- $(INPUT)" + @./$(BMARK)$(EXE) $(BMARK)-$(INPUT) 5 0 12345 1 + +debug: + @echo Running Debug C Version of the benchmark + @$(COMPILE_G) $(COMMON_SRC) $(C_SRC) -o $(BMARK)$(EXE) + @valgrind --leak-check=full ./$(BMARK)$(EXE) $(DATA_DIR) $(C_RESULT) + #@gdb ./$(BMARK)$(EXE) $(DATA_DIR) $(C_RESULT) + +profile: compile-prof + @echo -e "Data set\t\t- $(INPUT)" + @./$(BMARK)$(EXE) $(DATA_DIR) $(C_RESULT) + @gprof $(BMARK)$(EXE) + +compile-preload: + @$(COMPILE_C) $(TOOL_DIR)\preload.c -o $(TOOL_DIR)\preload + +compile: $(C_SRC) + @echo + @echo -e "Benchmark\t\t- $(BMARK)" + @$(COMPILE_C) $(COMMON_SRC) $(C_SRC) -lrt -L$(LIBLITMUS) -llitmus -lm -w -o $(BMARK)$(EXE) + +compile-prof: $(C_SRC) + @echo + @echo -e "Benchmark\t\t- $(BMARK)" + @$(COMPILE_PG) $(COMMON_SRC) $(C_SRC) -o $(BMARK)$(EXE) + +matlab-run: + @echo + @echo -e "Benchmark\t\t- $(BMARK)" + @echo -e "Data set\t\t- $(INPUT)" + @cd $(M_DIR); $(MATLAB_PATH) -glnx86 -nosplash -nodisplay -r "script_run_profile('$(M_DATA)', '$(M_RESULT)', '$(INPUT)', '$(M_COMMON)', '$(M_TOOLBOX)'); quit" | tee $(MTIMING_DIR)/Matlab_$(INPUT).txt + +mcc-run: + @echo Generating a C standalone application + cd $(M_DIR); $(MATLAB_PATH) -nosplash -nodesktop -r "mcc -m -v script_run_profile -d $(M_RESULT); quit" + +all: c-run matlab-run mcc-run + +clean: + @-rm $(BMARK) + + + + diff --git a/SD-VBS/common/makefiles/Makefile.include b/SD-VBS/common/makefiles/Makefile.include new file mode 100644 index 0000000..f1000b9 --- /dev/null +++ b/SD-VBS/common/makefiles/Makefile.include @@ -0,0 +1,16 @@ +find-dir-with = $(shell /usr/bin/perl -e 'chomp($$_ = `pwd`); while ($$_ ne "" && ! -e "$$_/$(1)") { m:(.*)/[^/]+/??:; $$_ = $$1; } print;') + +# define canonical directories in starsearch +ifndef TOP_DIR + export TOP_DIR := $(call find-dir-with,.SD-VBS) +endif + +export MAKEFILE_COMMON_DIR=$(TOP_DIR)/common/makefiles + +# backward compatibility + +ifeq ($(TOP_DIR),) +$(error file .SD-VBS not found -- try running 'gmake setup' at the top of your source tree) +endif + + diff --git a/SD-VBS/common/makefiles/Makefile.recurse b/SD-VBS/common/makefiles/Makefile.recurse new file mode 100644 index 0000000..ed575bb --- /dev/null +++ b/SD-VBS/common/makefiles/Makefile.recurse @@ -0,0 +1,41 @@ +# This file is included in the makefiles of the non-leaf nodes +# Thus the various targets in this file have to trickle down +# into the subdirectories +# List the subdirectories and call the target for each one of them + +################################################################ +# RECURSE +################################################################ +# Listing the subdirectories +SUBDIRS = $(patsubst %/Makefile,%,$(wildcard */Makefile)) + +RECURSE-DEPENDS = $(patsubst %,%.traverse,$(SUBDIRS)) + +all: recurse + +debug: recurse + +clean: recurse + +compile: recurse + +c-run: recurse + +matlab-run: recurse + +mcc-run: recurse + +recurse: $(RECURSE-DEPENDS) + +time-run: recurse + +preload-run: recurse + +run: recurse + +rt-run: recurse + +# MAKECMDGOALS contains the gmake target specified on the command line +# it is defined automatically by gmake +%.traverse: + $(MAKE) -C $* $(MAKECMDGOALS) diff --git a/SD-VBS/common/support/buildTable.py b/SD-VBS/common/support/buildTable.py new file mode 100644 index 0000000..1a1a6aa --- /dev/null +++ b/SD-VBS/common/support/buildTable.py @@ -0,0 +1,54 @@ +import re +import sys +import os + +def getExprName(fileName): + exprFileName = os.path.basename(fileName) + exprName = re.sub("\.txt", "", exprFileName) + exprName = re.sub("_","\t", exprName, 1) + exprName = re.sub("_", "", exprName) + return(exprName) + +def getBmrkName(fileName): + benchmarkDir = os.path.dirname(fileName) + benchmarkName = os.path.basename(benchmarkDir) + return(benchmarkName) + +def getCycleCountTup(fileName): + try: + inp = open(fileName, 'r') + except IOError, err: + print "ERROR: Could not open the inputFile:"+fileName + sys.exit(1) + globalTup = None + for currline in inp: + currline = currline.strip() + currline = currline.lower() + if(re.match("cycles elapsed", currline)): + valTup = re.findall("(\d+)", currline) + return(valTup) + + if(globalTup != None): + return(globalTup) + else: + print "ERROR: INVALID INPUT FILE:"+fileName + sys.exit(2) + +def main(): + if(len(sys.argv)<2): + print "USAGE: "+sys.argv[0]+" " + sys.exit(1) + + fileName = sys.argv[1] + exprName = getExprName(fileName) + benchmarkName = getBmrkName(fileName) + cycleCountTup = getCycleCountTup(fileName) + + print "%-20s %-20s %10s\n" % (benchmarkName,exprName,cycleCountTup[0]) + + + + + +if __name__=="__main__": + main() diff --git a/SD-VBS/common/support/buildTimeTable.py b/SD-VBS/common/support/buildTimeTable.py new file mode 100644 index 0000000..c718cb2 --- /dev/null +++ b/SD-VBS/common/support/buildTimeTable.py @@ -0,0 +1,55 @@ +import re +import sys +import os + +def getExprName(fileName): + exprFileName = os.path.basename(fileName) + exprName = re.sub("\.txt", "", exprFileName) + exprName = re.sub("_","\t", exprName, 1) + exprName = re.sub("_", "", exprName) + return(exprName) + +def getBmrkName(fileName): + benchmarkDir = os.path.dirname(fileName) + benchmarkName = os.path.basename(benchmarkDir) + return(benchmarkName) + +def getTimeTup(fileName): + try: + inp = open(fileName, 'r') + except IOError, err: + print "ERROR: Could not open the inputFile:"+fileName + sys.exit(1) + globalTup = None + for currline in inp: + currline = currline.strip() + currline = currline.lower() + if(re.match("real", currline)): + #valTup = re.findall("(\d+)", currline) + + return(currline[4:].strip()) + + if(globalTup != None): + return(globalTup) + else: + print "ERROR: INVALID INPUT FILE:"+fileName + sys.exit(2) + +def main(): + if(len(sys.argv)<2): + print "USAGE: "+sys.argv[0]+" " + sys.exit(1) + + fileName = sys.argv[1] + exprName = getExprName(fileName) + benchmarkName = getBmrkName(fileName) + timeTup = getTimeTup(fileName) + + print "%-20s %-20s %10s\n" % (benchmarkName,exprName,timeTup) + + + + + +if __name__=="__main__": + main() diff --git a/SD-VBS/common/toolbox/MultiNcut/MNcut.m b/SD-VBS/common/toolbox/MultiNcut/MNcut.m new file mode 100755 index 0000000..5486080 --- /dev/null +++ b/SD-VBS/common/toolbox/MultiNcut/MNcut.m @@ -0,0 +1,93 @@ +function [NcutDiscretes,eigenVectors,eigenValues] = MNcut(I,nsegs); +% +% [NcutDiscrete,eigenVectors,eigenValues] = MNcut(I,nsegs); +% +% + +[nr,nc,nb] = size(I); + +max_image_size = max(nr,nc); + +% modified by song, 06/13/2005 +% test parameters +if (1) % original settings + if (max_image_size>120) & (max_image_size<=500), + % use 3 levels, + data.layers.number=3; + data.layers.dist=3; + data.layers.weight=[3000,4000,10000]; + data.W.scales=[1,2,3];%[1,2,3]; + data.W.radius=[2,3,7];%[2,3,7]; + elseif (max_image_size >500), + % use 4 levels, + data.layers.number=4; + data.layers.dist=3; + data.layers.weight=[3000,4000,10000,20000]; + data.W.scales=[1,2,3,3]; + data.W.radius=[2,3,4,6]; + elseif (max_image_size <=120) + data.layers.number=2; + data.layers.dist=3; + data.layers.weight=[3000,10000]; + data.W.scales=[1,2]; + data.W.radius=[2,6]; + end +else % test setting + if (max_image_size>200) & (max_image_size<=500), + % use 3 levels, + data.layers.number=3; + data.layers.dist=3; + data.layers.weight=[3000,4000,10000]; + data.W.scales=[1,2,3];%[1,2,3]; + data.W.radius=[2,3,7];%[2,3,7]; + elseif (max_image_size >500), + % use 4 levels, + data.layers.number=4; + data.layers.dist=3; + data.layers.weight=[3000,4000,10000,20000]; + data.W.scales=[1,2,3,3]; + data.W.radius=[2,3,4,6]; + elseif (max_image_size <=200) + data.layers.number=2; + data.layers.dist=3; + data.layers.weight=[3000,10000]; + data.W.scales=[1,2]; + data.W.radius=[2,4]; + end + +end; + + +data.W.edgeVariance=0.1; %0.1 +data.W.gridtype='square'; +data.W.sigmaI=0.12;%0.12 +data.W.sigmaX=1000; +data.W.mode='mixed'; +data.W.p=0; +data.W.q=0; + +%eigensolver +data.dataGraphCut.offset = 100;% 10; %valeur sur diagonale de W (mieux vaut 10 pour valeurs negatives de W) +data.dataGraphCut.maxiterations=50;% voir +data.dataGraphCut.eigsErrorTolerance=1e-2;%1e-6; +data.dataGraphCut.valeurMin=1e-6;%1e-5;% utilise pour tronquer des valeurs et sparsifier des matrices +data.dataGraphCut.verbose = 0; + +data.dataGraphCut.nbEigenValues=max(nsegs); + +disp('computeEdge'); +[multiWpp,ConstraintMat, Wind,data,emag,ephase]= computeMultiW (I,data); + +disp('Ncut'); +[eigenVectors,eigenValues]= eigSolve (multiWpp,ConstraintMat,data); + +%NcutDiscretes = zeros(nr,nc,length(nsegs)); +NcutDiscretes = zeros(nr,nc,(nsegs)); + +for j=1:length(nsegs), + nseg = nsegs(j); + [nr,nc,nb] = size(eigenVectors(:,:,1:nseg)); + [NcutDiscrete,evrotated] =discretisation(reshape(eigenVectors(:,:,1:nb),nr*nc,nb),nr,nc); + NcutDiscretes(:,:,j) = NcutDiscrete; +end + diff --git a/SD-VBS/common/toolbox/MultiNcut/MNcutDemo.m b/SD-VBS/common/toolbox/MultiNcut/MNcutDemo.m new file mode 100755 index 0000000..972a4eb --- /dev/null +++ b/SD-VBS/common/toolbox/MultiNcut/MNcutDemo.m @@ -0,0 +1,34 @@ +% MNcutDemo.m +% created by song, 06/13/2005 +% an exmaple of how to use and display MNcut + +num_segs = [20]; +imageSize = 800; + +img_filename = '/u/ikkjin/Benchmark/stitch/data/test/capitol/img1.jpg'; + +I=readimage(img_filename,imageSize); + +[SegLabel,eigenVectors,eigenValues]= MNcut(I,num_segs); + +for j=1:size(SegLabel,3), + [gx,gy] = gradient(SegLabel(:,:,j)); + bw = (abs(gx)>0.1) + (abs(gy) > 0.1); + + figure(1);clf; J1=showmask(double(I),bw); imagesc(J1);axis image; axis off; + set(gca, 'Position', [0 0 1 1]); + + % cm = sprintf('print -djpeg %s/file%.4d-%.2d.jpg',OutputDir,id,num_segs(j)); disp(cm);eval(cm); + + + % figure(10);imagesc(SegLabel(:,:,j));axis image; axis off; + % set(gca, 'Position', [0 0 1 1]); + % cm = sprintf('print -djpeg %s/Seg%.4d-%.2d.jpg',OutputDir,id,num_segs(j));disp(cm);eval(cm); + + % pause; +end + +% fname = files(id).name; +%cm = sprintf('save %s/SegLabl%.4d.mat I SegLabel fname',OutputDir,id); disp(cm); eval(cm); +%cm = sprintf('save %s/SegEig%.4d.mat eigenVectors eigenValues',OutputDir,id);disp(cm); eval(cm); + diff --git a/SD-VBS/common/toolbox/MultiNcut/README.tex b/SD-VBS/common/toolbox/MultiNcut/README.tex new file mode 100755 index 0000000..5970fb2 --- /dev/null +++ b/SD-VBS/common/toolbox/MultiNcut/README.tex @@ -0,0 +1,9 @@ +1) You need to first compile the .c files,type + +>> compileAll('.'); + +2) the top level function is called MNcut.m + + + + diff --git a/SD-VBS/common/toolbox/MultiNcut/a_times_b_cmplx.c b/SD-VBS/common/toolbox/MultiNcut/a_times_b_cmplx.c new file mode 100755 index 0000000..25def92 --- /dev/null +++ b/SD-VBS/common/toolbox/MultiNcut/a_times_b_cmplx.c @@ -0,0 +1,405 @@ +/*================================================================ +a_times_b_cmplx.c = used by a couple of mex functions +provide Matrix vector multiplications, +and solve triangular systems +(sparse matrix and full vector) + +CSC_CmplxVecMult_CAB_double, CSR_CmplxVecMult_CAB_double, +CSCsymm_CmplxVecMult_CAB_double added by Mirko Visontai (10/24/2003) + +*=================================================================*/ +# include "math.h" + + +/*C<-a*A*B+C*/ +void CSC_VecMult_CaABC_double( + const int m, const int k, const double alpha, + const double *val, const int *indx, + const int *pntrb, + const double *b, + double *c) +{ + int i,j,jb,je; + + for (i=0;i!=k;i++){ + jb = pntrb[i]; + je = pntrb[i+1]; + for (j=jb;j!=je;j++) + c[indx[j]] += alpha * b[i] * val[j]; + } +} + +/*C<-a*A'*B+C*/ +void CSR_VecMult_CaABC_double( + const int k, const int m, const double alpha, + const double *val, const int *indx, + const int *pntrb, + const double *b, + double *c) +{ + double t; + const double *pval; + int i,j,jb,je; + + pval = val; + for (i=0;i!=m;i++) { + t = 0; + jb = pntrb[i]; + je = pntrb[i+1]; + for (j=jb;j!=je;j++) + t += alpha * b[indx[j]] * (*pval++); + c[i] += t; + } +} + + +/*C<-A*b */ +void CSC_VecMult_CAB_double( + const int m, const int k, /*nb_rows, nb_columns*/ + const double *val, const int *indx, + const int *pntrb, + const double *b, + double *c + ) +{ + int i,j,jb,je; + double *pc=c; + for (i=0;i!=m;i++) *pc++ = 0; + + for (i=0;i!=k;i++){ + jb = pntrb[i]; + je = pntrb[i+1]; + for (j=jb;j!=je;j++) + c[indx[j]] += b[i] * val[j]; + } +} + +/*C<-A*b (complex)*/ +void CSC_CmplxVecMult_CAB_double( + const int m, const int k, + const double *valr, const double *vali, + const int *indx, + const int *pntrb, + const double *br, const double *bi, + double *cr, double *ci + ) +{ + int i,j,jb,je; + double *pcr=cr; + double *pci=ci; + for (i=0;i!=m;i++){ + *pcr++ = 0.0; + *pci++ = 0.0; + } + + for (i=0;i!=k;i++){ + jb = pntrb[i]; + je = pntrb[i+1]; + for (j=jb;j!=je;j++){ + cr[indx[j]] += (br[i] * valr[j]) - (bi[i] * vali[j]); + ci[indx[j]] += (br[i] * vali[j]) + (bi[i] * valr[j]); + } + } +} + +/*C<-A'*b + plus rapide que CSC_VecMult_CAB_double */ +void CSR_VecMult_CAB_double( + const int k, const int m, + const double *val, const int *indx, + const int *pntrb, + const double *b, + double *c + ) +{ + double t; + const double *pval; + double *pc=c; + int i,j,jb,je; + + for (i=0;i!=m;i++) *pc++ = 0; + + pval = val; + for (i=0;i!=m;i++) { + t = 0; + jb = pntrb[i]; + je = pntrb[i+1]; + for (j=jb;j!=je;j++) + t += b[indx[j]] * (*pval++); + c[i] += t; + } +} + +/*C<-A'*b (complex) + plus rapide que CSC_VecMult_CAB_double */ +void CSR_CmplxVecMult_CAB_double( + const int k, const int m, + const double *valr, const double *vali, + const int *indx, + const int *pntrb, + const double *br, const double *bi, + double *cr, double *ci + ) +{ + double tr, ti; + const double *pvalr; + const double *pvali; + double *pcr=cr; + double *pci=ci; + int i,j,jb,je; + + for (i=0;i!=m;i++){ + *pcr++ = 0.0; + *pci++ = 0.0; + } + + pvalr = valr; + pvali = vali; + for (i=0;i!=m;i++) { + tr = 0.0; + ti = 0.0; + jb = pntrb[i]; + je = pntrb[i+1]; + for (j=jb;j!=je;j++){ + tr += (br[indx[j]] * (*pvalr)) - (bi[indx[j]] * (*pvali)); + ti += (br[indx[j]] * (*pvali++)) + (bi[indx[j]] * (*pvalr++)); + } + cr[i] += tr; + ci[i] += ti; + } +} + + + +/* C<-A*b (A is symmetric) */ +void CSRsymm_VecMult_CAB_double( + const int k, const int m, + const double *val, const int *indx, + const int *pntrb, + const double *b, + double *c + ) +{ + const double *pval; + double *pc=c; + int i,j; + int jj; + int rpntrb, rpntre; + int index, nvals; + + + for (i=0;i!=m;i++) *pc++ = 0; + pval = val; + for (j=0;j!=k;j++){ + rpntrb = pntrb[j]; + rpntre = pntrb[j+1]; + for (jj=rpntrb;jj!=rpntre;jj++) { + index = indx[jj]; + if ( index == j ) { + c[j] += b[j] * (*pval++); + continue; + } + if ( index > j ) { + c[index] += b[j] * (*pval); + + c[j] += b[index] * (*pval++); + } + else { + pval++; + } + } + } +} + + +/* C<-A*b (A is symmetric and complex) */ +void CSRsymm_CmplxVecMult_CAB_double( + const int k, const int m, + const double *valr, const double *vali, + const int *indx, + const int *pntrb, + const double *br, const double *bi, + double *cr, double *ci + ) +{ + const double *pvalr, *pvali; + double *pcr=cr; + double *pci=ci; + int i,j; + int jj; + int rpntrb, rpntre; + int index, nvals; + + + for (i=0;i!=m;i++){ + *pcr++ = 0.0; + *pci++ = 0.0; + } + + pvalr = valr; + pvali = vali; + for (j=0;j!=k;j++){ + rpntrb = pntrb[j]; + rpntre = pntrb[j+1]; + for (jj=rpntrb;jj!=rpntre;jj++) { + index = indx[jj]; + if ( index == j ) { + cr[j] += (br[j] * (*pvalr)) - (bi[j] * (*pvali)); + ci[j] += (br[j] * (*pvali++)) + (bi[j] * (*pvalr++)); + continue; + } + if ( index > j ) { + cr[index] += (br[j] * (*pvalr)) - (bi[j] * (*pvali)); + ci[index] += (br[j] * (*pvali)) + (bi[j] * (*pvalr)); + + cr[j] += (br[index] * (*pvalr)) - (bi[index] * (*pvali)); + ci[j] += (br[index] * (*pvali++)) + (bi[index] * (*pvalr++)); + } + else { + pvalr++; + pvali++; + } + + } + } +} + + +/*C<-A\B; with Lower triangular A*/ +void CSC_VecTriangSlvLD_CAB_double( + const int m, + const double *val, + const int *indx, const int *pntrb, + const double *b, + double *c) +{ + int i, j, jb, je; + double *pc=c; + double z; + + for (i=0;i!=m;i++){ + *pc = b[i]; + pc++; + } + + pc=c; + for (i=0;i!=m;i++) { + jb = pntrb[i]; + je = pntrb[i+1]; + z = pc[i] / val[jb]; + pc[i] = z; + for (j=jb+1;j1) { + mexErrMsgTxt("Too many output arguments"); + } + + /* get edgel information */ + nr = mxGetM(in[0]); + nc = mxGetN(in[0]); + if ( nr*nc ==0 || nr != mxGetM(in[1]) || nc != mxGetN(in[1]) ) { + mexErrMsgTxt("Edge magnitude and phase shall be of the same image size"); + } + emag = mxGetPr(in[0]); + ephase = mxGetPr(in[1]); + np = nr * nc; + + /* get new index pair */ + if (!mxIsUint32(in[2]) | !mxIsUint32(in[3])) { + mexErrMsgTxt("Index pair shall be of type UINT32"); + } + if (mxGetM(in[3]) * mxGetN(in[3]) != np + 1) { + mexErrMsgTxt("Wrong index representation"); + } + pi = mxGetData(in[2]); + pj = mxGetData(in[3]); + + /* create output */ + out[0] = mxCreateSparse(np,np,pj[np],mxREAL); + if (out[0]==NULL) { + mexErrMsgTxt("Not enough memory for the output matrix"); + } + w = mxGetPr(out[0]); + ir = mxGetIr(out[0]); + jc = mxGetJc(out[0]); + + /* find my sigma */ + if (nargin<5) { + sigma = 0; + for (k=0; ksigma) { sigma = emag[k]; } + } + sigma = sigma / 6; + /* printf("sigma = %6.5f",sigma); */ + } else { + sigma = mxGetScalar(in[4]); + } + a = 0.5 / (sigma * sigma); + + /* computation */ + total = 0; + for (j=0; j= abs(dj)) { + slope = dj / di; + step = (iy>=jy) ? 1 : -1; + + iip1 = jy; + jjp1 = jx; + + + for (ii=0;ii maxori){ + maxori = z; + } + } + + iip1 = iip2; + jjp1 = jjp2; + phase1 = phase2; + } + + /* sample in j direction */ + } else { + slope = di / dj; + step = (ix>=jx) ? 1: -1; + + jjp1 = jx; + iip1 = jy; + + + for (jj=0;jj maxori){ + maxori = z; + } + + } + + iip1 = iip2; + jjp1 = jjp2; + phase1 = phase2; + } + } + + maxori = 0.5 * maxori; + maxori = exp(-maxori * maxori * a); + } + ir[total] = i; + + w[total] = maxori; + total = total + 1; + + } /* i */ + } /* j */ + + jc[np] = total; +} diff --git a/SD-VBS/common/toolbox/MultiNcut/affinityic.dll b/SD-VBS/common/toolbox/MultiNcut/affinityic.dll new file mode 100755 index 0000000..67e4d64 Binary files /dev/null and b/SD-VBS/common/toolbox/MultiNcut/affinityic.dll differ diff --git a/SD-VBS/common/toolbox/MultiNcut/affinityic.mexa64 b/SD-VBS/common/toolbox/MultiNcut/affinityic.mexa64 new file mode 100755 index 0000000..2648387 Binary files /dev/null and b/SD-VBS/common/toolbox/MultiNcut/affinityic.mexa64 differ diff --git a/SD-VBS/common/toolbox/MultiNcut/affinityic.mexglx b/SD-VBS/common/toolbox/MultiNcut/affinityic.mexglx new file mode 100755 index 0000000..c296845 Binary files /dev/null and b/SD-VBS/common/toolbox/MultiNcut/affinityic.mexglx differ diff --git a/SD-VBS/common/toolbox/MultiNcut/batch_MNcut.m b/SD-VBS/common/toolbox/MultiNcut/batch_MNcut.m new file mode 100755 index 0000000..d4dcb3c --- /dev/null +++ b/SD-VBS/common/toolbox/MultiNcut/batch_MNcut.m @@ -0,0 +1,48 @@ +data_dir = '/data/insecure/qihuizhu/baseball/Gray/train/'; +save_dir = '/home/songgang/project/MultiNcut/batch_result_MNcut'; + +num_segs = [20]; +imageSize = 200; + + +filelist = dir(fullfile(data_dir, '*.tif')); + +nb_file = max(size(filelist)); + + +tic; +for ii = 1:nb_file + fprintf(2, 'Segmenting image: %s ...\n', filelist(ii).name); + + img_filename = fullfile(data_dir, filelist(ii).name); + I=readimage(img_filename,imageSize); + + + [SegLabel,eigenVectors,eigenValues]= MNcut(I,num_segs); + + for j=1:size(SegLabel,3), + [gx,gy] = gradient(SegLabel(:,:,j)); + bw = (abs(gx)>0.1) + (abs(gy) > 0.1); + + figure(1);clf; J1=showmask(double(I),bw); imagesc(J1);axis image; axis off; + set(gca, 'Position', [0 0 1 1]); + set(gca, 'Position', [0 0 1 1]); + [PATHSTR,NAME,EXT,VERSN] = fileparts(filelist(ii).name); + print('-f1', '-djpeg90', fullfile(save_dir, sprintf('%s%s-%d.jpg', NAME,'-out', num_segs(j)))); + + + % cm = sprintf('print -djpeg %s/file%.4d-%.2d.jpg',OutputDir,id,num_segs(j)); disp(cm);eval(cm); + + + % figure(10);imagesc(SegLabel(:,:,j));axis image; axis off; + % set(gca, 'Position', [0 0 1 1]); + % cm = sprintf('print -djpeg %s/Seg%.4d-%.2d.jpg',OutputDir,id,num_segs(j));disp(cm);eval(cm); + +% keyboard; + end + + + +end; +toc; +fprintf(2, ' %d files done\n', nb_file); diff --git a/SD-VBS/common/toolbox/MultiNcut/cimgnbmap.c b/SD-VBS/common/toolbox/MultiNcut/cimgnbmap.c new file mode 100755 index 0000000..44af715 --- /dev/null +++ b/SD-VBS/common/toolbox/MultiNcut/cimgnbmap.c @@ -0,0 +1,198 @@ +/*================================================================ +* function [i,j] = cimgnbmap([nr,nc], nb_r, sample_rate) +* computes the neighbourhood index matrix of an image, +* with each neighbourhood sampled. +* Input: +* [nr,nc] = image size +* nb_r = neighbourhood radius, could be [r_i,r_j] for i,j +* sample_rate = sampling rate, default = 1 +* Output: +* [i,j] = each is a column vector, give indices of neighbour pairs +* UINT32 type +* i is of total length of valid elements, 0 for first row +* j is of length nr * nc + 1 +* +* See also: imgnbmap.c, id2cind.m +* +* Examples: +* [i,j] = imgnbmap(10, 20); % [10,10] are assumed +* +* Stella X. Yu, Nov 12, 2001. + +% test sequence: +nr = 15; +nc = 15; +nbr = 1; +[i,j] = cimgnbmap([nr,nc], nbr); +mask = csparse(i,j,ones(length(i),1),nr*nc); +show_dist_w(rand(nr,nc),mask) + +*=================================================================*/ + +# include "mex.h" +# include "math.h" + +void mexFunction( + int nargout, + mxArray *out[], + int nargin, + const mxArray *in[] +) +{ + /* declare variables */ + int nr, nc, np, nb, total; + double *dim, sample_rate; + int r_i, r_j, a1, a2, b1, b2, self, neighbor; + int i, j, k, s, t, nsamp, th_rand, no_sample; + /* unsigned long *p, *qi, *qj; */ + unsigned int *p, *qi, *qj; + + /* check argument */ + if (nargin < 2) { + mexErrMsgTxt("Two input arguments required"); + } + if (nargout> 2) { + mexErrMsgTxt("Too many output arguments."); + } + + /* get image size */ + i = mxGetM(in[0]); + j = mxGetN(in[0]); + dim = mxGetData(in[0]); + nr = (int)dim[0]; + if (j>1 || i>1) { + nc = (int)dim[1]; + } else { + nc = nr; + } + np = nr * nc; + + /* get neighbourhood size */ + i = mxGetM(in[1]); + j = mxGetN(in[1]); + dim = mxGetData(in[1]); + r_i = (int)dim[0]; + if (j>1 || i>1) { + r_j = (int)dim[1]; + } else { + r_j = r_i; + } + if (r_i<0) { r_i = 0; } + if (r_j<0) { r_j = 0; } + + /* get sample rate */ + if (nargin==3) { + sample_rate = (mxGetM(in[2])==0) ? 1: mxGetScalar(in[2]); + } else { + sample_rate = 1; + } + /* prepare for random number generator */ + if (sample_rate<1) { + srand( (unsigned)time( NULL ) ); + th_rand = (int)ceil((double)RAND_MAX * sample_rate); + no_sample = 0; + } else { + sample_rate = 1; + th_rand = RAND_MAX; + no_sample = 1; + } + + /* figure out neighbourhood size */ + + nb = (r_i + r_i + 1) * (r_j + r_j + 1); + if (nb>np) { + nb = np; + } + nb = (int)ceil((double)nb * sample_rate); +/*printf("nb=%d\n",nb);*/ + /* intermediate data structure */ + /* p = mxCalloc(np * (nb+1), sizeof(unsigned long)); */ + p = mxCalloc(np * (nb+1), sizeof(unsigned int)); + if (p==NULL) { + mexErrMsgTxt("Not enough space for my computation."); + } + + /* computation */ + total = 0; + for (j=0; j=nc) { b2 = nc-1; } + + /* i range */ + a1 = i - r_i; + if (a1<0) { a1 = 0; } + a2 = i + r_i; + if (a2>=nr) { a2 = nr-1; } + + /* number of more samples needed */ + nsamp = nb - p[self]; + /*if (nsamp<0) + {printf("nsamp=%d\n",nsamp);}*/ + k = 0; + t = b1; + s = i + 1; + if (s>a2) { + s = a1; + t = t + 1; + } + + + while (ka2) { + s = a1; + t = t + 1; + } + } /* k */ + total = total + p[self]; + } /* i */ + + } /* j */ + + /* i, j */ + + out[0] = mxCreateNumericMatrix(total, 1, mxUINT32_CLASS, mxREAL); + out[1] = mxCreateNumericMatrix(np+1, 1, mxUINT32_CLASS, mxREAL); + qi = mxGetData(out[0]); + qj = mxGetData(out[1]); + + if (out[0]==NULL || out[1]==NULL) { + mexErrMsgTxt("Not enough space for the output matrix."); + } + + total = 0; + for (j=0; j 2) { + mexErrMsgTxt("Too many output arguments."); + } + + /* get image size */ + i = mxGetM(in[0]); + j = mxGetN(in[0]); + dim = mxGetData(in[0]); + nr = (int)dim[0]; + if (j>1 || i>1) { + nc = (int)dim[1]; + } else { + nc = nr; + } + np = nr * nc; + + /* get neighbourhood size */ + i = mxGetM(in[1]); + j = mxGetN(in[1]); + dim = mxGetData(in[1]); + r_i = (int)dim[0]; + if (j>1 || i>1) { + r_j = (int)dim[1]; + } else { + r_j = r_i; + } + if (r_i<0) { r_i = 0; } + if (r_j<0) { r_j = 0; } + + /* get sample rate */ + if (nargin==3) { + sample_rate = (mxGetM(in[2])==0) ? 1: mxGetScalar(in[2]); + } else { + sample_rate = 1; + } + /* prepare for random number generator */ + if (sample_rate<1) { + srand( (unsigned)time( NULL ) ); + th_rand = (int)ceil((double)RAND_MAX * sample_rate); + no_sample = 0; + } else { + sample_rate = 1; + th_rand = RAND_MAX; + no_sample = 1; + } + + /* figure out neighbourhood size */ + + nb = (r_i + r_i) * (r_j + r_j)+1; + if (nb>np) { + nb = np; + } + nb = (int)ceil((double)nb * sample_rate); +/*printf("nb=%d\n",nb);*/ + /* intermediate data structure */ + /* p = mxCalloc(np * (nb+1), sizeof(unsigned long)); */ + p = mxCalloc(np * (nb+1), sizeof(unsigned int)); + if (p==NULL) { + mexErrMsgTxt("Not enough space for my computation."); + } + + /* computation */ + total = 0; + for (j=0; j=nc) { b2 = nc-1; } + + /* i range */ + /*a1 = i - r_i; + if (a1<0) { a1 = 0; }*/ + a2 = i + r_i; + if (a2>=nr) { a2 = nr-1; } + + /* number of more samples needed */ + nsamp = nb - p[self]; + /*if (nsamp<0) + {printf("nsamp=%d\n",nsamp);}*/ + k = 0; + t = b1; + s = i + 1; + if (s>a2) { + s = i; + t = t + 1; + } + + + while (ka2) { s = i; t = t + 1; + } + } + else {t=t+1;} + } /* k */ + total = total + p[self]; + } /* i */ + + } /* j */ + + /* i, j */ + + out[0] = mxCreateNumericMatrix(total, 1, mxUINT32_CLASS, mxREAL); + out[1] = mxCreateNumericMatrix(np+1, 1, mxUINT32_CLASS, mxREAL); + qi = mxGetData(out[0]); + qj = mxGetData(out[1]); + + if (out[0]==NULL || out[1]==NULL) { + mexErrMsgTxt("Not enough space for the output matrix."); + } + + total = 0; + for (j=0; j 2) { + mexErrMsgTxt("Too many output arguments."); + } + + + /* get image size */ + + i = mxGetM(in[0]); + j = mxGetN(in[0]); + dim = mxGetData(in[0]); + nr = (int)dim[0]; + if (j>1 || i>1) { + nc = (int)dim[1]; + } else { + nc = nr; + } + np = nr * nc; + + + /* get neighbourhood size */ + i = mxGetM(in[1]); + j = mxGetN(in[1]); + dim = mxGetData(in[1]); + r_i = (int)dim[0]; + + if (j>1 || i>1) { + r_j = (int)dim[1]; + } else { + r_j = r_i; + } + + if (r_i<0) { r_i = 0; } + + if (r_j<0) { r_j = 0; } + + + + /* get sample rate */ + + if (nargin==3) { + + sample_rate = (mxGetM(in[2])==0) ? 1: mxGetScalar(in[2]); + + } else { + + sample_rate = 1; + + } + + /* prepare for random number generator */ + if (sample_rate<1) { + srand( (unsigned)time( NULL ) ); + + th_rand = (int)ceil((double)RAND_MAX * sample_rate); + no_sample = 0; + } else { + + sample_rate = 1; + th_rand = RAND_MAX; + no_sample = 1; + } + + + /* figure out neighbourhood size */ + + nb = (4*r_i) + (4*r_j)+1; + if (nb>np) { + nb = np; + } + nb = (int)ceil((double)nb * sample_rate); + +/*printf("nb=%d\n",nb);*/ + + /* intermediate data structure */ + + /* p = mxCalloc(np * (nb+1), sizeof(unsigned long));*/ + p = mxCalloc(np * (nb+1), sizeof(unsigned int)); + + if (p==NULL) { + + mexErrMsgTxt("Not enough space for my computation."); + + } + + + + /* computation */ + + total = 0; + for (j=0; j=nc) { b2 = nc-1; } + + + /* i range */ + /*a1 = i - r_i; + + if (a1<0) { a1 = 0; }*/ + a2 = i + r_i; + if (a2>=nr) { a2 = nr-1; } + + + /* number of more samples needed */ + + nsamp = nb - p[self]; + + /*if (nsamp<0) + {printf("nsamp=%d\n",nsamp);}*/ + k = 0; + t = b1; + s = i + 1; + + if (s>a2) { + s = i; + t = t + 1; + } + + + + while (ka2) { + t = t + 1; + if (i+j-t>=0) + {s = i+j-t;} + else + {s=i;} + } + } + else { + if (s==i+j-t) {s=i;} + else{ if (s==i && s+t-j=0) + {s = i+j-t;} + else + {s=i;} + } + + } + } + + } /* k */ + + total = total + p[self]; + } /* i */ + + } /* j */ + + + + /* i, j */ + + out[0] = mxCreateNumericMatrix(total, 1, mxUINT32_CLASS, mxREAL); + + out[1] = mxCreateNumericMatrix(np+1, 1, mxUINT32_CLASS, mxREAL); + + qi = mxGetData(out[0]); + + qj = mxGetData(out[1]); + + + if (out[0]==NULL || out[1]==NULL) { + + mexErrMsgTxt("Not enough space for the output matrix."); + + } + + + + total = 0; + + for (j=0; j1) + for j=i-1:-1:1 + Wpp{i}=[C{j,i}',Wpp{i}]; + end + end + if (i1) +% for j=i-1:-1:1 +% Wpp{i}=[sparse(p(i)*q(i),p(j)*q(j)),Wpp{i}]; +% end +% end +% if (i2 + for i=3:n + piqi=p(i)*q(i); + if i~=n + constraintMat=[constraintMat,[sparse(sum(p(1:i-2).*q(1:i-2)),piqi);-C{i-1,i};speye(piqi);sparse(pq-sum(p(2:i).*q(2:i)),piqi)]]; + else + constraintMat=[constraintMat,[sparse(sum(p(1:i-2).*q(1:i-2)),piqi);-C{i-1,i};speye(piqi)]]; + end + end + end + + % saving useful information + %subgrids, p and q + data.subgrid=subgrid; + data.p=p; + data.q=q; diff --git a/SD-VBS/common/toolbox/MultiNcut/discretisation.m b/SD-VBS/common/toolbox/MultiNcut/discretisation.m new file mode 100755 index 0000000..70b5650 --- /dev/null +++ b/SD-VBS/common/toolbox/MultiNcut/discretisation.m @@ -0,0 +1,49 @@ +function [SegLabel,EigenVectors]=discretisation(EigenVectors,nr,nc) +% +% EigenvectorsDiscrete=discretisation(EigenVectors) +% +% Input: EigenVectors = continuous Ncut vector, size = ndata x nbEigenvectors +% Output EigenvectorsDiscrete = discrete Ncut vector, size = ndata x nbEigenvectors +% +% Timothee Cour, Stella Yu, Jianbo Shi, 2004 + +[n,k]=size(EigenVectors); + +vm = sqrt(sum(EigenVectors.*EigenVectors,2)); +EigenVectors = EigenVectors./repmat(vm,1,k); + +R=zeros(k); +R(:,1)=EigenVectors(1+round(rand(1)*(n-1)),:)'; +c=zeros(n,1); +for j=2:k + c=c+abs(EigenVectors*R(:,j-1)); + [minimum,i]=min(c); + R(:,j)=EigenVectors(i,:)'; +end + +lastObjectiveValue=0; +exitLoop=0; +nbIterationsDiscretisation = 0; +nbIterationsDiscretisationMax = 20;%voir +while exitLoop== 0 + nbIterationsDiscretisation = nbIterationsDiscretisation + 1 ; + EigenvectorsDiscrete = discretisationEigenVectorData(EigenVectors*R); + [U,S,V] = svd(EigenvectorsDiscrete'*EigenVectors,0); + NcutValue=2*(n-trace(S)); + + if abs(NcutValue-lastObjectiveValue) < eps | nbIterationsDiscretisation > nbIterationsDiscretisationMax + exitLoop=1; + else + lastObjectiveValue = NcutValue; + R=V*U'; + end +end + +%%%% + +SegLabel = zeros(nr,nc); +for j=1:size(EigenvectorsDiscrete,2), + SegLabel = SegLabel + j*reshape(EigenvectorsDiscrete(:,j),nr,nc); +end +EigenVectors = reshape(EigenVectors,nr,nc,size(EigenVectors,2)); + diff --git a/SD-VBS/common/toolbox/MultiNcut/discretisationEigenVectorData.m b/SD-VBS/common/toolbox/MultiNcut/discretisationEigenVectorData.m new file mode 100755 index 0000000..4626e3d --- /dev/null +++ b/SD-VBS/common/toolbox/MultiNcut/discretisationEigenVectorData.m @@ -0,0 +1,12 @@ +function Y = discretisationEigenVectorData(EigenVector) +% Y = discretisationEigenVectorData(EigenVector) +% +% discretizes previously rotated eigenvectors in discretisation +% Timothee Cour, Stella Yu, Jianbo Shi, 2004 + +[n,k]=size(EigenVector); + + +[Maximum,J]=max(EigenVector'); + +Y=sparse(1:n,J',1,n,k); diff --git a/SD-VBS/common/toolbox/MultiNcut/doog1.m b/SD-VBS/common/toolbox/MultiNcut/doog1.m new file mode 100755 index 0000000..dd8e87b --- /dev/null +++ b/SD-VBS/common/toolbox/MultiNcut/doog1.m @@ -0,0 +1,32 @@ +function H=doog1(sig,r,th,N); +% H=doog1(sig,r,th,N); + + +% by Serge Belongie + +no_pts=N; % no. of points in x,y grid + +[x,y]=meshgrid(-(N/2)+1/2:(N/2)-1/2,-(N/2)+1/2:(N/2)-1/2); + +phi=pi*th/180; +sigy=sig; +sigx=r*sig; +R=[cos(phi) -sin(phi); sin(phi) cos(phi)]; +C=R*diag([sigx,sigy])*R'; + +X=[x(:) y(:)]; + +Gb=gaussian(X,[0 0]',C); +Gb=reshape(Gb,N,N); + +m=R*[0 sig]'; + +a=1; +b=-1; + +% make odd-symmetric filter +Ga=gaussian(X,m/2,C); +Ga=reshape(Ga,N,N); +Gb=rot90(Ga,2); +H=a*Ga+b*Gb; + diff --git a/SD-VBS/common/toolbox/MultiNcut/doog2.m b/SD-VBS/common/toolbox/MultiNcut/doog2.m new file mode 100755 index 0000000..a0511cb --- /dev/null +++ b/SD-VBS/common/toolbox/MultiNcut/doog2.m @@ -0,0 +1,38 @@ +function G=doog2(sig,r,th,N); +% G=doog2(sig,r,th,N); +% Make difference of offset gaussians kernel +% theta is in degrees +% (see Malik & Perona, J. Opt. Soc. Amer., 1990) +% +% Example: +% >> imagesc(doog2(1,12,0,64,1)) +% >> colormap(gray) + +% by Serge Belongie + +no_pts=N; % no. of points in x,y grid + +[x,y]=meshgrid(-(N/2)+1/2:(N/2)-1/2,-(N/2)+1/2:(N/2)-1/2); + +phi=pi*th/180; +sigy=sig; +sigx=r*sig; +R=[cos(phi) -sin(phi); sin(phi) cos(phi)]; +C=R*diag([sigx,sigy])*R'; + +X=[x(:) y(:)]; + +Gb=gaussian(X,[0 0]',C); +Gb=reshape(Gb,N,N); + +m=R*[0 sig]'; +Ga=gaussian(X,m,C); +Ga=reshape(Ga,N,N); +Gc=rot90(Ga,2); + +a=-1; +b=2; +c=-1; + +G = a*Ga + b*Gb + c*Gc; + diff --git a/SD-VBS/common/toolbox/MultiNcut/eigSolve.m b/SD-VBS/common/toolbox/MultiNcut/eigSolve.m new file mode 100755 index 0000000..cfb64fc --- /dev/null +++ b/SD-VBS/common/toolbox/MultiNcut/eigSolve.m @@ -0,0 +1,5 @@ +function [eigenVectors,s]= eigSolve (multiWpp,ConstraintMat,data) + +[v,s] = quickNcutHardBiais2(multiWpp,ConstraintMat,data.dataGraphCut.nbEigenValues,data.dataGraphCut); +v=v(1:data.p(1)*data.q(1),:); +eigenVectors=reshape(v,data.p(1),data.q(1),data.dataGraphCut.nbEigenValues); diff --git a/SD-VBS/common/toolbox/MultiNcut/fft_filt_2.m b/SD-VBS/common/toolbox/MultiNcut/fft_filt_2.m new file mode 100755 index 0000000..9c84e96 --- /dev/null +++ b/SD-VBS/common/toolbox/MultiNcut/fft_filt_2.m @@ -0,0 +1,29 @@ +function FI=fft_filt_2(V,FB,sf); +% FI=fft_filt_2(V,FB,sf); +% fft-based filtering +% requires image to be called "V" +% and filters to be in FB +% sf is the subsampling factor +% +% FI is the result + +[M1,M2,N3]=size(FB); +% prepare FFT of image for filtering +[N1,N2]=size(V); +I=zeros(size(V)+[M1-1 M2-1]); +I(1:N1,1:N2)=V; +N1s=length(1:sf:N1); +N2s=length(1:sf:N2); +IF=fft2(I); +FI=zeros(N1s,N2s,N3); + +% apply filters +for n=1:N3; + f=rot90(FB(:,:,n),2); + fF=fft2(f,N1+M1-1,N2+M2-1); + IfF=IF.*fF; + If=real(ifft2(IfF)); + If=If(ceil((M1+1)/2):ceil((M1+1)/2)+N1-1,ceil((M2+1)/2):ceil((M2+1)/2)+N2-1); + FI(:,:,n)=If(1:sf:N1,1:sf:N2); +end + diff --git a/SD-VBS/common/toolbox/MultiNcut/gaussian.m b/SD-VBS/common/toolbox/MultiNcut/gaussian.m new file mode 100755 index 0000000..509b129 --- /dev/null +++ b/SD-VBS/common/toolbox/MultiNcut/gaussian.m @@ -0,0 +1,31 @@ +function p=gaussian(x,m,C); +% p=gaussian(x,m,C); +% +% Evaluate the multi-variate density with mean vector m and covariance +% matrix C for the input vector x. +% +% p=gaussian(X,m,C); +% +% Vectorized version: Here X is a matrix of column vectors, and p is +% a vector of probabilities for each vector. + +d=length(m); + +if size(x,1)~=d + x=x'; +end +N=size(x,2); + +detC = det(C); +if rcond(C)0) { + ir[k] = mxGetIr(in[k]); + jc[k] = mxGetJc(in[k]); + } + } + + out[0] = mxCreateDoubleMatrix(m[1],1,mxREAL); + y = mxGetPr(out[0]); + + + y1 = mxCalloc(n[2], sizeof(double)); + y2 = mxCalloc(m[3], sizeof(double)); + y2bis = mxCalloc(m[3], sizeof(double)); + y3 = mxCalloc(m[1], sizeof(double)); + y4 = mxCalloc(m[1], sizeof(double)); + y5 = mxCalloc(n[2], sizeof(double)); + y5bis = mxCalloc(n[2], sizeof(double)); + y6 = mxCalloc(n[2], sizeof(double)); + + CSR_VecMult_CAB_double(m[2],n[2],pr[2],ir[2],jc[2],pr[0],y1); + CSR_VecTriangSlvLD_CAB_double(m[3],pr[3],ir[3],jc[3],y1,y2bis); + CSC_VecTriangSlvUD_CAB_double(m[3],pr[3],ir[3],jc[3],y2bis,y2); + for(k=0;k0) { + ir[k] = mxGetIr(in[k]); + jc[k] = mxGetJc(in[k]); + } + } + + out[0] = mxCreateDoubleMatrix(m[1],1,mxREAL); + y = mxGetPr(out[0]); + + + y1 = mxCalloc(n[2], sizeof(double)); + y2 = mxCalloc(m[3], sizeof(double)); + y2bis = mxCalloc(m[3], sizeof(double)); + y3 = mxCalloc(m[1], sizeof(double)); + y4 = mxCalloc(m[1], sizeof(double)); + y5 = mxCalloc(n[2], sizeof(double)); + y5bis = mxCalloc(n[2], sizeof(double)); + y6 = mxCalloc(n[2], sizeof(double)); + + CSR_VecMult_CAB_double(m[2],n[2],pr[2],ir[2],jc[2],pr[0],y1); + CSR_VecTriangSlvLD_CAB_double(m[3],pr[3],ir[3],jc[3],y1,y2bis); + CSC_VecTriangSlvUD_CAB_double(m[3],pr[3],ir[3],jc[3],y2bis,y2); + for(k=0;k1) { + mexErrMsgTxt("Too many output arguments"); + } + + /* get edgel information */ + nr = mxGetM(in[0]); + nc = mxGetN(in[0]); + if ( nr*nc ==0 || nr != mxGetM(in[1]) || nc != mxGetN(in[1]) ) { + mexErrMsgTxt("Edge magnitude and phase shall be of the same image size"); + } + emag = mxGetPr(in[0]); + ephase = mxGetPr(in[1]); + np = nr * nc; + + /*get subgrid information*/ + + tmp = mxGetData(in[5]); + nrSubgrid = (int)tmp[0]; + tmp = mxGetData(in[6]); + ncSubgrid = (int)tmp[0]; + + /* printf("nrSubgrid=%d\n",nrSubgrid); + printf("ncSubgrid=%d\n",ncSubgrid); */ + if (nrSubgrid* ncSubgrid != mxGetM(in[4])*mxGetN(in[4])) { + mexErrMsgTxt("Error in the size of the subgrid"); + } + subgrid = mxGetData(in[4]); + nW = nrSubgrid * ncSubgrid; + + /* get new index pair */ + if (!mxIsUint32(in[2]) | !mxIsUint32(in[3])) { + mexErrMsgTxt("Index pair shall be of type UINT32"); + } + if (mxGetM(in[3]) * mxGetN(in[3]) != nW + 1) { + mexErrMsgTxt("Wrong index representation"); + } + pi = mxGetData(in[2]); + pj = mxGetData(in[3]); + subpi = mxGetData(in[7]); + /*{printf("pi[50] = %d\n",pi[50]);} + {printf("subpi[5] = %d\n",subpi[5]);} + {printf("subpi[6] = %d\n",subpi[6]);} + {printf("subpi[4] = %d\n",subpi[4]);}*/ + + /* create output */ /*!!!!!!!!!!!!!!!!!!!!!!!changer taille output!!!!!!!!!!*/ + out[0] = mxCreateSparse(nW,nW,pj[nW],mxREAL); + if (out[0]==NULL) { + mexErrMsgTxt("Not enough memory for the output matrix"); + } + w = mxGetPr(out[0]); + ir = mxGetIr(out[0]); + jc = mxGetJc(out[0]); + + /* find my sigma */ + if (nargin<9) { + sigma = 0; + for (k=0; ksigma) { sigma = emag[k]; } + } + sigma = sigma / 6; + printf("sigma = %6.5f",sigma); + } else { + sigma = mxGetScalar(in[8]); + } + a = 0.5 / (sigma * sigma); + + /* computation */ + total = 0; + + for (j=0; j= abs(dj)) { + slope = dj / di; + step = (iy>=jy) ? 1 : -1; + + iip1 = jy; + jjp1 = jx; + + + for (ii=0;ii maxori){ + maxori = z; + } + } + + iip1 = iip2; + jjp1 = jjp2; + phase1 = phase2; + } + + /* sample in j direction */ + } else { + slope = di / dj; + step = (ix>=jx) ? 1: -1; + + jjp1 = jx; + iip1 = jy; + + + for (jj=0;jj maxori){ + maxori = z; + } + + } + + iip1 = iip2; + jjp1 = jjp2; + phase1 = phase2; + } + } + + maxori = 0.5 * maxori; + maxori = exp(-maxori * maxori * a); + } + /*if (total<20) {printf("subpi[k] = %d\n",subpi[k]);}*/ + + ir[total] = (int)subpi[k]; +/*if (total<20) {printf("ir[total] = %d\n",ir[total]);}*/ + w[total] = maxori; + total = total + 1; + + } /* i */ + } /*j*/ + /*printf("total = %d\n",total);*/ + /*printf("ir[100] = %d\n",ir[100]);*/ + jc[nW] = total; +} diff --git a/SD-VBS/common/toolbox/MultiNcut/multiAffinityic.dll b/SD-VBS/common/toolbox/MultiNcut/multiAffinityic.dll new file mode 100755 index 0000000..f9b6bc9 Binary files /dev/null and b/SD-VBS/common/toolbox/MultiNcut/multiAffinityic.dll differ diff --git a/SD-VBS/common/toolbox/MultiNcut/multiAffinityic.mexa64 b/SD-VBS/common/toolbox/MultiNcut/multiAffinityic.mexa64 new file mode 100755 index 0000000..9a2a3cc Binary files /dev/null and b/SD-VBS/common/toolbox/MultiNcut/multiAffinityic.mexa64 differ diff --git a/SD-VBS/common/toolbox/MultiNcut/multiAffinityic.mexglx b/SD-VBS/common/toolbox/MultiNcut/multiAffinityic.mexglx new file mode 100755 index 0000000..ec11a0e Binary files /dev/null and b/SD-VBS/common/toolbox/MultiNcut/multiAffinityic.mexglx differ diff --git a/SD-VBS/common/toolbox/MultiNcut/multiIntensityFirstLayer.c b/SD-VBS/common/toolbox/MultiNcut/multiIntensityFirstLayer.c new file mode 100755 index 0000000..0cae523 --- /dev/null +++ b/SD-VBS/common/toolbox/MultiNcut/multiIntensityFirstLayer.c @@ -0,0 +1,126 @@ +/*================================================================ +* function w = intensityWppc(image,pi,pj,rMin,sigmaX,sigmaIntensite,valeurMinW ) +* Input: +* [pi,pj] = index pair representation for MALTAB sparse matrices +* Output: +* w = affinity with IC at [pi,pj] +* + +pixels i and j (corresponding to the sampling in pi,pj) are fully connected when d(i,j) <= rmin; + +% test sequence +f = synimg(10); +[i,j] = cimgnbmap(size(f),2); +[ex,ey,egx,egy] = quadedgep(f); +a = affinityic(ex,ey,egx,egy,i,j) +show_dist_w(f,a); + +* Stella X. Yu, Nov 19, 2001. +*=================================================================*/ + +# include "mex.h" +# include "math.h" + +void mexFunction( + int nargout, + mxArray *out[], + int nargin, + const mxArray *in[] +) +{ + /* declare variables */ + int nr, nc, np, total; + int i, j, k, ix, iy, jx, jy; + int *ir, *jc; + int squareDistance; + /* unsigned long *pi, *pj; */ +unsigned int *pi, *pj; + double *w; + + double temp,a1,a2,wij; + double rMin; + double sigmaX, sigmaIntensite,valeurMinW; + double *image; + + /* check argument */ + if (nargin<7) { + mexErrMsgTxt("Four input arguments required"); + } + if (nargout>1) { + mexErrMsgTxt("Too many output arguments"); + } + + /* get edgel information */ + nr = mxGetM(in[0]); + nc = mxGetN(in[0]); + np = nr * nc; + + image = mxGetPr(in[0]); + + + + /* get new index pair */ + if (!mxIsUint32(in[1]) | !mxIsUint32(in[2])) { + mexErrMsgTxt("Index pair shall be of type UINT32"); + } + if (mxGetM(in[2]) * mxGetN(in[2]) != np + 1) { + mexErrMsgTxt("Wrong index representation"); + } + pi = mxGetData(in[1]); + pj = mxGetData(in[2]); + + /* create output */ + out[0] = mxCreateSparse(np,np,pj[np],mxREAL); + if (out[0]==NULL) { + mexErrMsgTxt("Not enough memory for the output matrix"); + } + w = mxGetPr(out[0]); + ir = mxGetIr(out[0]); + jc = mxGetJc(out[0]); + + rMin = mxGetScalar(in[3]); + sigmaX = mxGetScalar(in[4]); + sigmaIntensite= mxGetScalar(in[5]); + valeurMinW = mxGetScalar(in[6]); + + a1 = 1.0/ (sigmaX*sigmaX); + a2 = 1.0 / (sigmaIntensite*sigmaIntensite ); + + /* computation */ + total = 0; + for (j=0; j1) { + mexErrMsgTxt("Too many output arguments"); + } + + /* get edgel information */ + nr = mxGetM(in[0]); + nc = mxGetN(in[0]); + np = nr * nc; + /*printf("size: %d, %d, %d\n", nc, nr, np); */ + image = mxGetPr(in[0]); + + + /*get subgrid information*/ + + tmp = mxGetData(in[8]); + nrSubgrid = (int)tmp[0]; + + /* printf("image end = %f ", image[np-1]); */ + + tmp = mxGetData(in[9]); + ncSubgrid = (int)tmp[0]; + + if (nrSubgrid* ncSubgrid != mxGetM(in[7])*mxGetN(in[7])) { + mexErrMsgTxt("Error in the size of the subgrid"); + } + subgrid = mxGetData(in[7]); + nW = nrSubgrid * ncSubgrid; + + + + + /* get new index pair */ + if (!mxIsUint32(in[1]) | !mxIsUint32(in[2])) { + mexErrMsgTxt("Index pair shall be of type UINT32"); + } + if (mxGetM(in[2]) * mxGetN(in[2]) != nW + 1) { + mexErrMsgTxt("Wrong index representation"); + } + pi = mxGetData(in[1]); + pj = mxGetData(in[2]); + subpi = mxGetData(in[10]); + + /* create output */ + out[0] = mxCreateSparse(nW,nW,pj[nW],mxREAL); + if (out[0]==NULL) { + mexErrMsgTxt("Not enough memory for the output matrix"); + } + + w = mxGetPr(out[0]); + ir = mxGetIr(out[0]); + jc = mxGetJc(out[0]); + + + rMin = mxGetScalar(in[3]); + sigmaX = mxGetScalar(in[4]); + sigmaIntensite= mxGetScalar(in[5]); + valeurMinW = mxGetScalar(in[6]); + + a1 = 1.0/ (sigmaX*sigmaX); + a2 = 1.0 / (sigmaIntensite*sigmaIntensite ); + + + + /* computation */ + total = 0; + for (j=0; jnp-1)) {printf("badddddd!");} + /* printf("t = %d\n",t); + printf("j = %d\n",j); */ + jc[j] = total; + jx = t / nr; /* col */ + jy = t % nr; /* row */ + /* printf("pj[j+1] = %d\n",pj[j+1]); */ + + for (k=pj[j]; k5000*5000 ) {printf("trouble! [%d,%d]\n",k,(int)subpi[k]);} */ + + w[total] = wij; + + total = total + 1; + + } /* i */ + + + } /* j */ + + jc[nW] = total; +} diff --git a/SD-VBS/common/toolbox/MultiNcut/multiIntensityWppc.dll b/SD-VBS/common/toolbox/MultiNcut/multiIntensityWppc.dll new file mode 100755 index 0000000..16146c1 Binary files /dev/null and b/SD-VBS/common/toolbox/MultiNcut/multiIntensityWppc.dll differ diff --git a/SD-VBS/common/toolbox/MultiNcut/multiIntensityWppc.mexa64 b/SD-VBS/common/toolbox/MultiNcut/multiIntensityWppc.mexa64 new file mode 100755 index 0000000..525ca62 Binary files /dev/null and b/SD-VBS/common/toolbox/MultiNcut/multiIntensityWppc.mexa64 differ diff --git a/SD-VBS/common/toolbox/MultiNcut/multiIntensityWppc.mexglx b/SD-VBS/common/toolbox/MultiNcut/multiIntensityWppc.mexglx new file mode 100755 index 0000000..a17fa03 Binary files /dev/null and b/SD-VBS/common/toolbox/MultiNcut/multiIntensityWppc.mexglx differ diff --git a/SD-VBS/common/toolbox/MultiNcut/quadedgep2.m b/SD-VBS/common/toolbox/MultiNcut/quadedgep2.m new file mode 100755 index 0000000..5041377 --- /dev/null +++ b/SD-VBS/common/toolbox/MultiNcut/quadedgep2.m @@ -0,0 +1,188 @@ +% function [xs,ys,gx,gy,par,threshold,mag,mage,g,FIe,FIo,mago] = quadedgep(I,par,threshold); +% Input: +% I = image +% par = vector for 4 parameters +% [number of filter orientations, number of scale, filter size, elongation] +% To use default values, put 0. +% threshold = threshold on edge strength +% Output: +% [x,y,gx,gy] = locations and gradients of an ordered list of edgels +% x,y could be horizontal or vertical or 45 between pixel sites +% but it is guaranteed that there [floor(y) + (floor(x)-1)*nr] +% is ordered and unique. In other words, each edgel has a unique pixel id. +% par = actual par used +% threshold = actual threshold used +% mag = edge magnitude +% mage = phase map +% g = gradient map at each pixel +% [FIe,FIo] = odd and even filter outputs +% mago = odd filter output of optimum orientation + +% Stella X. Yu, 2001 + +% This is the multi scale version of the filtering +% For the moment the parameters are defined by default. See line 34 + + +function [x,y,gx,gy,par,threshold,mag_s,mage,g,FIe,FIo,mago] = quadedgep2(I,par,data,threshold); + + +if nargin<4 | isempty(threshold), + threshold = 0.1; +end + +[r,c] = size(I); +def_par = [4,30,3]; + +display_on = 1; + +% take care of parameters, any missing value is substituted by a default value +if nargin<2 | isempty(par), + par = def_par; +end +% par(end+1:4)=0; +% par = par(:); +% j = (par>0); +% have_value = [ j, 1-j ]; +% j = 1; n_filter = have_value(j,:) * [par(j); def_par(j)]; +% j = 2; n_scale = have_value(j,:) * [par(j); def_par(j)]; +% j = 3; winsz = have_value(j,:) * [par(j); def_par(j)]; +% j = 4; enlong = have_value(j,:) * [par(j); def_par(j)]; + +n_ori = par(1); %if it doesn't work, par<-def_par + +winsz = par(2); +enlong = par(3); + +% always make filter size an odd number so that the results will not be skewed +j = winsz/2; +if not(j > fix(j) + 0.1), + winsz = winsz + 1; +end + +% filter the image with quadrature filters +if (isempty(data.W.scales)) + error ('no scales entered'); +end + +n_scale=length(data.W.scales); +filter_scales=data.W.scales; +% +% if strcmp(data.dataWpp.mode,'multiscale') +% n_scale=size((data.dataWpp.scales),2); +% filter_scales=data.dataWpp.scales; +% else +% filter_scales=data.dataWpp.scales(1); +% n_scale=1; +% end +% if n_scale>0&&strcmp(data.dataWpp.mode,'multiscale') +% if (~isempty(data.dataWpp.scales)) +% filter_scales=data.dataWpp.scales; +% else +% filter_scales=zeros(1,n_scale); +% +% for i=1:n_scale, +% filter_scales(i)=(sqrt(2))^(i-1); +% end +% data.dataWpp.scales=filter_scales; +% end +% else filter_scale=1; +% data.dataWpp.scales=filter_scales; +% end +% +% %%%%%%% juste pour que ca tourne +% if ~strcmp(data.dataWpp.mode,'multiscale') +% filter_scales=data.dataWpp.scales(1); +% n_scale=4; +% end +% %%%%%%%%%%%% + +FBo = make_filterbank_odd2(n_ori,filter_scales,winsz,enlong); +FBe = make_filterbank_even2(n_ori,filter_scales,winsz,enlong); +n = ceil(winsz/2); +f = [fliplr(I(:,2:n+1)), I, fliplr(I(:,c-n:c-1))]; +f = [flipud(f(2:n+1,:)); f; flipud(f(r-n:r-1,:))]; +FIo = fft_filt_2(f,FBo,1); +FIo = FIo(n+[1:r],n+[1:c],:); +FIe = fft_filt_2(f,FBe,1); +FIe = FIe(n+[1:r],n+[1:c],:); + +% compute the orientation energy and recover a smooth edge map +% pick up the maximum energy across scale and orientation +% even filter's output: as it is the second derivative, zero cross localize the edge +% odd filter's output: orientation + +[nr,nc,nb] = size(FIe); + +FIe = reshape(FIe, nr,nc,n_ori,length(filter_scales)); +FIo = reshape(FIo, nr,nc,n_ori,length(filter_scales)); + +mag_s = zeros(nr,nc,n_scale); +mag_a = zeros(nr,nc,n_ori); + +mage = zeros(nr,nc,n_scale); +mago = zeros(nr,nc,n_scale); +mage = zeros(nr,nc,n_scale); +mago = zeros(nr,nc,n_scale); + + + +for i = 1:n_scale, + mag_s(:,:,i) = sqrt(sum(FIo(:,:,:,i).^2,3)+sum(FIe(:,:,:,i).^2,3)); + mag_a = sqrt(FIo(:,:,:,i).^2+FIe(:,:,:,i).^2); + [tmp,max_id] = max(mag_a,[],3); + + base_size = nr * nc; + id = [1:base_size]'; + mage(:,:,i) = reshape(FIe(id+(max_id(:)-1)*base_size+(i-1)*base_size*n_ori),[nr,nc]); + mago(:,:,i) = reshape(FIo(id+(max_id(:)-1)*base_size+(i-1)*base_size*n_ori),[nr,nc]); + + mage(:,:,i) = (mage(:,:,i)>0) - (mage(:,:,i)<0); + + if display_on, + ori_incr=pi/n_ori; % to convert jshi's coords to conventional image xy + ori_offset=ori_incr/2; + theta = ori_offset+([1:n_ori]-1)*ori_incr; % orientation detectors + % [gx,gy] are image gradient in image xy coords, winner take all + + ori = theta(max_id); + ori = ori .* (mago(:,:,i)>0) + (ori + pi).*(mago(:,:,i)<0); + gy{i} = mag_s(:,:,i) .* cos(ori); + gx{i} = -mag_s(:,:,i) .* sin(ori); + g = cat(3,gx{i},gy{i}); + + % phase map: edges are where the phase changes + mag_th = max(max(mag_s(:,:,i))) * threshold; + eg = (mag_s(:,:,i)>mag_th); + h = eg & [(mage(2:r,:,i) ~= mage(1:r-1,:,i)); zeros(1,nc)]; + v = eg & [(mage(:,2:c,i) ~= mage(:,1:c-1,i)), zeros(nr,1)]; + [y{i},x{i}] = find(h | v); + k = y{i} + (x{i}-1) * nr; + h = h(k); + v = v(k); + y{i} = y{i} + h * 0.5; % i + x{i} = x{i} + v * 0.5; % j + t = h + v * nr; + gx{i} = g(k) + g(k+t); + k = k + (nr * nc); + gy{i} = g(k) + g(k+t); + +% figure(1); +% clf; +% imagesc(I);colormap(gray); +% hold on; +% quiver(x,y,gx,gy); hold off; +% title(sprintf('scale = %d, press return',i)); + + % pause; + 0; +else + x = []; + y = []; + gx = []; + gy =[]; + g= []; + end +end + + diff --git a/SD-VBS/common/toolbox/MultiNcut/quickNcutHardBiais2.m b/SD-VBS/common/toolbox/MultiNcut/quickNcutHardBiais2.m new file mode 100755 index 0000000..3ca1046 --- /dev/null +++ b/SD-VBS/common/toolbox/MultiNcut/quickNcutHardBiais2.m @@ -0,0 +1,187 @@ +% function [v,s] = quickNcutHardBiais(W,U,nbEigenValues,dataGraphCut) +%ligne 35 : changement tim +%[v,s] = ncut(W,nbEigenValues,[],offset); +%devient : +%[v,s] = tim_ncut_rapide(W,nbEigenValues,[],offset); +%et eigs devient tim_eigs + +% Input: +% W = affinity matrix +% U = hard constraint matrix, could be a cell of partial grouping +% nbEigenValues = number of eigenvectors +% offset = regularization factor, default = 0 +% Output: +% v = eigenvector +% s = eigenvalue of (W,d), s.t. U' * x = 0. + +% call eigs using my own * operation + +% Stella X. Yu, Jan 2002. + +function [v,s] = quickNcutHardBiais2(W,U,nbEigenValues,dataGraphCut)%voir : rajouter sigma +n = size(W,1); +nbEigenValues = min(nbEigenValues,n); + +offset = dataGraphCut.offset; +%offset = 2; + +% degrees and regularization +d = sum(abs(W),2); +dr = 0.5 * (d - sum(W,2)); +d = d + offset * 2; +dr = dr + offset; +W = W + spdiags(dr,0,n,n); +clear dr + +% normalize +Dinvsqrt = 1./sqrt(d+eps); +P = spmtimesd(W,Dinvsqrt,Dinvsqrt); +clear W; + +% if max(max(P-P')) < 1e-10 %ou eps +% %S = sparse(1:n,1:n,0.5); +% P =max(P,P'); +% % P=S*(P+P'); +% %P=0.5*(P+P'); +% options.issym = 1; +% end +P = sparsifyc(P,dataGraphCut.valeurMin); +options.issym = 1; + +Ubar = spmtimesd(U,Dinvsqrt,[]); +%Ubar = sparsifyc(Ubar,dataGraphCut.valeurMin); %voir + +options.disp = dataGraphCut.verbose; +options.maxit = dataGraphCut.maxiterations; +options.tol = dataGraphCut.eigsErrorTolerance; + +options.v0 = ones(size(P,1),1);%voir + +options.p = max(35,2*nbEigenValues); %voir +options.p = min(options.p , n); + +% nouvelle idee : factorisation de Cholesky +C=Ubar'*Ubar; +%permutation = symamd(C); +%R = cholinc(C(permutation,permutation)); +t_chol_Ubar = cputime; +[R,ooo] = cholinc(C,'0'); +t_chol_Ubar = cputime - t_chol_Ubar; +%if error occurs, check if Ubar = sparsifyc(Ubar,dataGraphCut.valeurMin); +%sparsifies too much + + +% compute H = (Ubar'*Ubar)^(-1) +% t_inv_H = cputime; +% H = inv(sparsifyc(Ubar' * Ubar,dataGraphCut.valeurMin)); %changer +% t_inv_H = cputime - t_inv_H; +% H = sparsifyc(H,dataGraphCut.valeurMin); +% tEigs = cputime; +% if options.issym & max(max(H-H')) < 1e-10 +% [vbar,s,convergence] = tim_eigs(@mex_projection_inv_symmetric,n,nbEigenValues,'lm',options,triu(P),Ubar,triu(H)); +% else +% [vbar,s,convergence] = tim_eigs(@mex_projection_inv,n,nbEigenValues,'lm',options,P,Ubar,H); +% end +% tEigs = cputime - tEigs; +% + + + +R = sparsifyc(R,dataGraphCut.valeurMin); +tEigs = cputime; +if options.issym + [vbar,s,convergence] = tim_eigs(@mex_projection_QR_symmetric,n,nbEigenValues,'lm',options,tril(P),Ubar,R); +else + [vbar,s,convergence] = tim_eigs(@mex_projection_QR,n,nbEigenValues,'lm',options,P,Ubar,R); +end +tEigs = cputime - tEigs; + + +%afficheTexte(sprintf('\n\nTemps ecoule pendant eigs : %g',tEigs),dataGraphCut.verbose,2); +%afficheTexte(sprintf('\nTemps ecoule pendant chol(Ubar''*Ubar) : %g',t_chol_Ubar),dataGraphCut.verbose); +if convergence~=0 + afficheTexte(sprintf(' (Non-convergence)'),dataGraphCut.verbose); +end + + +%disp(sprintf('nnz(P) : %f\n',nnz(P))); +%disp(sprintf('nnz(Ubar) : %f\n',nnz(Ubar))); +%disp(sprintf('nnz(R) : %f\n',nnz(R))); +%disp(sprintf('nnz(global) : %f\n',nnz(P) + 4 * nnz(Ubar) + 4*nnz(R))); + + + +s = real(diag(s)); +[x,y] = sort(-s); +s = -x; +vbar = vbar(:,y); + + +v = spdiags(Dinvsqrt,0,n,n) * vbar; + +for i=1:size(v,2) + %v(:,i) = v(:,i) / max(abs(v(:,i))); + v(:,i) = (v(:,i) / norm(v(:,i)) )*norm(ones(n,1)); + if v(1,i)~=0 + v(:,i) = - v(:,i) * sign(v(1,i)); + end +end + +% % nouvelle idee : factorisation de Cholesky +% t_chol_Ubar = cputime; +% R = chol(Ubar' * Ubar); +% t_chol_Ubar = cputime - t_chol_Ubar; +% R = sparsifyc(R,dataGraphCut.valeurMin); +% tEigs = cputime; +% if options.issym +% [vbar,s,convergence] = tim_eigs(@mex_projection_QR_symmetric,n,nbEigenValues,'lm',options,triu(P),Ubar,R); +% else +% [vbar,s,convergence] = tim_eigs(@mex_projection_QR,n,nbEigenValues,'lm',options,P,Ubar,R); +% end +% tEigs = cputime - tEigs; + + +% % compute H = (Ubar'*Ubar)^(-1) +% t_inv_H = cputime; +% H = inv(sparsifyc(Ubar' * Ubar,dataGraphCut.valeurMin)); %changer +% t_inv_H = cputime - t_inv_H; +% H = sparsifyc(H,dataGraphCut.valeurMin); +% tEigs = cputime; +% if options.issym & max(max(H-H')) < 1e-10 +% [vbar,s,convergence] = tim_eigs(@mex_projection_inv_symmetric,n,nbEigenValues,'lm',options,triu(P),Ubar,triu(H)); +% else +% [vbar,s,convergence] = tim_eigs(@mex_projection_inv,n,nbEigenValues,'lm',options,P,Ubar,H); +% end +% tEigs = cputime - tEigs; + + + +% % idee de mon rapport... semble pas marcher car R = qr(Ubar,0) est plus +% % lent que H = inv(sparsifyc(Ubar' * Ubar,dataGraphCut.valeurMin)); +% t_qr_Ubar = cputime; +% R = qr(Ubar,0); +% t_qr_Ubar = cputime - t_qr_Ubar; +% R = sparsifyc(R,dataGraphCut.valeurMin); +% tEigs2 = cputime; +% if options.issym +% [vbar2,s2,convergence] = tim_eigs(@mex_projection_QR_symmetric,n,nbEigenValues,'lm',options,triu(P),Ubar,R); +% else +% [vbar2,s2,convergence] = tim_eigs(@mex_projection_QR,n,nbEigenValues,'lm',options,P,Ubar,R); +% end +% tEigs2 = cputime - tEigs2; + + + +% idee de Jianbo... semble pas marcher car on a besoin de prendre k maximal +% dans [A,S,B] = svds(Ubar,k); +% +% [A,S,B] = svds(Ubar,300); +% A = sparsifyc(A,dataGraphCut.valeurMin); +% tEigs = cputime; +% [vbar,s,convergence] = tim_eigs(@mex_projection_svd,n,nbEigenValues,'lm',options,P,A); + +% afficheTexte(sprintf('\ninv(H) : %g',t_inv_H),dataGraphCut.verbose); +% afficheTexte(sprintf('\n\nTemps ecoule pendant eigs : %g',tEigs2),dataGraphCut.verbose,2); +% afficheTexte(sprintf('\nqr(Ubar) : %g',t_qr_Ubar),dataGraphCut.verbose); +% disp(sprintf('nnz(H) : %f\n',nnz(H))); +% disp(sprintf('nnz(global) : %f\n',nnz(P) + 4 * nnz(Ubar) + 2*nnz(H))); diff --git a/SD-VBS/common/toolbox/MultiNcut/read_data.m b/SD-VBS/common/toolbox/MultiNcut/read_data.m new file mode 100755 index 0000000..c0929c0 --- /dev/null +++ b/SD-VBS/common/toolbox/MultiNcut/read_data.m @@ -0,0 +1,13 @@ + +%fnames = dir('/home/jshi/Results_DLIB/SegLabl*.mat'); + +fnames = dir('/data/jshi/DLIB/Results/Results_DLIB/SegLabl*.mat'); + +for j=1:length(fnames), + cm = sprintf('load /data/jshi/DLIB/Results/Results_DLIB/%s',fnames(j).name); + disp(cm);eval(cm); +figure(1);imagesc(I); colormap(gray); axis image; +figure(2); imagesc(SegLabel); axis image; + +pause; +end diff --git a/SD-VBS/common/toolbox/MultiNcut/readimage.m b/SD-VBS/common/toolbox/MultiNcut/readimage.m new file mode 100755 index 0000000..e45fa19 --- /dev/null +++ b/SD-VBS/common/toolbox/MultiNcut/readimage.m @@ -0,0 +1,15 @@ +function I = readimage(fn,maxSize); + +Io = imread(fn); +[nr,nc,nb] = size(Io); + +if nb>1, + I = rgb2gray(Io); +else + I= Io; +end + +%maxSize = 400; +if max(nr,nc) > maxSize, + I = imresize(I,maxSize/max(nr,nc)); +end diff --git a/SD-VBS/common/toolbox/MultiNcut/run_script.m b/SD-VBS/common/toolbox/MultiNcut/run_script.m new file mode 100755 index 0000000..3d2e8c6 --- /dev/null +++ b/SD-VBS/common/toolbox/MultiNcut/run_script.m @@ -0,0 +1,60 @@ +%% set path for the MNcut code + +if 1, +% MNcutDir = '/home/jshi/Matlab/Toolbox/MultiNcut'; + MNcutDir = 'C:\qihuizhu\Checkout\Human\Source\MultiNcut_new\MultiNcut'; + path(path,MNcutDir); +end + +%% set the image input and output dir. +% imagedir = '/data/jshi/DLIB/image.cd'; +% imagedir = 'C:\qihuizhu\Checkout\Human\Source\Data\test'; +imagedir = 'C:\qihuizhu\Checkout\Human\Data\Current\baby_case5'; +% imageformat = 'ppm'; +imageformat = 'tif'; + +% OutputDir = '/home/jshi/Results_DLIB'; +% OutputDir = 'C:\qihuizhu\Checkout\Human\Source\Data\test'; +OutputDir = 'C:\qihuizhu\Checkout\Human\Result\Segmentation\MultiNcut_new_03.07'; + +a = dir(OutputDir); +if (length(a) == 0), + cm = sprintf('mkdir %s',OutputDir); + disp(cm); eval(cm); +end + +files = dir(sprintf('%s/*.%s',imagedir,imageformat)); + +%% image size definition +imageSize = 400; + +% for id =11:200, +for id = 1:length(files) + %for id = 19:19, + I=readimage(sprintf('%s/%s',imagedir,files(id).name),imageSize); + + num_segs = [10, 20]; + + tic + [SegLabel,eigenVectors,eigenValues]= MNcut(I,num_segs); + toc + + for j=1:size(SegLabel,3), + [gx,gy] = gradient(SegLabel(:,:,j)); + bw = (abs(gx)>0.1) + (abs(gy) > 0.1); + + figure(1);clf; J1=showmask(double(I),bw); imagesc(J1);axis image; + cm = sprintf('print -djpeg %s/file%.4d-%.2d.jpg',OutputDir,id,num_segs(j)); disp(cm);eval(cm); + + + figure(10);imagesc(SegLabel(:,:,j));axis image; + cm = sprintf('print -djpeg %s/Seg%.4d-%.2d.jpg',OutputDir,id,num_segs(j));disp(cm);eval(cm); + +% pause; + end + + fname = files(id).name; + %cm = sprintf('save %s/SegLabl%.4d.mat I SegLabel fname',OutputDir,id); disp(cm); eval(cm); + %cm = sprintf('save %s/SegEig%.4d.mat eigenVectors eigenValues',OutputDir,id);disp(cm); eval(cm); + +end diff --git a/SD-VBS/common/toolbox/MultiNcut/showmask.m b/SD-VBS/common/toolbox/MultiNcut/showmask.m new file mode 100755 index 0000000..6fd1142 --- /dev/null +++ b/SD-VBS/common/toolbox/MultiNcut/showmask.m @@ -0,0 +1,65 @@ +% function RGB=showmask(V,M,hue); +% Input: +% V = image +% M = nonnegative mask +% hue = a number in [0,1], red,yellow,green,cyan,...,red +% a char, 'r','g','b','y','c','m' +% or a matrix of the same size of image +% eg. hue = mask1 * 0.7 + mask2 * 1; +% +% Output: +% RGB = an RGB image with V as shades and M as saturated hues +% If no output is required, this image is displayed. + +% Stella X. YU, 2000. Based on Jianbo Shi's version. + +function RGB=showmask(V,M,hue); + +if nargin<3 | isempty(hue), + hue = 0; +end +if ischar(hue), + switch hue, + case 'r', hue = 1.0; + case 'g', hue = 0.3; + case 'b', hue = 0.7; + case 'y', hue = 0.15; + case 'c', hue = 0.55; + case 'm', hue = 0.85; + end +end + + +V=V-min(V(:)); +V=V/max(V(:)); +V=.25+0.75*V; %brighten things up a bit + +M = double(M); +M = M-min(M(:)); +M = M/max(M(:)); + +H = hue+zeros(size(V)); +S = M; +RGB = hsv2rgb(H,S,V); + +if nargout>0, + return; +end + +hold off; image(RGB); axis('image'); +s = cell(1,2); +if isempty(inputname(1)), + s{1} = 'image'; +else + s{1} = inputname(1); +end +if isempty(inputname(2)), + s{2} = 'mask'; +else + s{2} = inputname(2); +end +title(sprintf('%s and colored %s',s{1},s{2})); + +if nargout==0, + clear RGB; +end diff --git a/SD-VBS/common/toolbox/MultiNcut/sparsifyc.c b/SD-VBS/common/toolbox/MultiNcut/sparsifyc.c new file mode 100755 index 0000000..82fca98 --- /dev/null +++ b/SD-VBS/common/toolbox/MultiNcut/sparsifyc.c @@ -0,0 +1,232 @@ +/*================================================================= +* syntax: SPMX = SPARSIFY(MX, THRES) +* +* SPARSIFY - sparsify the input matrix, i.e. ignore the values +* of the matrix which are below a threshold +* +* Input: - MX: m-by-n matrix (sparse or full) +* - THRES: threshold value (double) +* +* Output: - SPMX: m-by-n sparse matrix only with values +* whose absolut value is above the given threshold +* +* Written by Mirko Visontai (10/24/2003) +*=================================================================*/ + + +#include +#include "mex.h" + +void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) +{ + /* Declare variable */ + int i,m,n,nzmax,newnnz,col,processed,passed; + int starting_row_index, current_row_index, stopping_row_index; + double *in_pr,*in_pi,*out_pr,*out_pi; + int *in_ir,*in_jc,*out_ir,*out_jc; + double thres; + + /* Check for proper number of input and output arguments */ + if ((nlhs != 1) || (nrhs != 2)){ + mexErrMsgTxt("usage: SPMX = SPARSIFY(MX, THRES)."); + } + /* if matrix is complex threshold the norm of the numbers */ + if (mxIsComplex(prhs[0])){ + /* Check data type of input argument */ + if (mxIsSparse(prhs[0])){ + + /* read input */ + in_pr = mxGetPr(prhs[0]); + in_pi = mxGetPi(prhs[0]); + in_ir = mxGetIr(prhs[0]); + in_jc = mxGetJc(prhs[0]); + nzmax = mxGetNzmax(prhs[0]); + m = mxGetM(prhs[0]); + n = mxGetN(prhs[0]); + thres = mxGetScalar(prhs[1]); + + /* Count new nonzeros */ + newnnz=0; + for(i=0; ithres) {newnnz++;} + } + + if (newnnz>0){ + /* create output */ + plhs[0] = mxCreateSparse(m,n,newnnz,mxCOMPLEX); + if (plhs[0]==NULL) + mexErrMsgTxt("Could not allocate enough memory!\n"); + out_pr = mxGetPr(plhs[0]); + out_pi = mxGetPr(plhs[0]); + out_ir = mxGetIr(plhs[0]); + out_jc = mxGetJc(plhs[0]); + passed = 0; + out_jc[0] = 0; + for (col=0; col thres){ + + out_pr[passed]=in_pr[current_row_index]; + out_pi[passed]=in_pi[current_row_index]; + out_ir[passed]=in_ir[current_row_index]; + out_jc[col+1] = out_jc[col+1]+1; + passed++; + } + } + } + } + } + else{ + plhs[0] = mxCreateSparse(m,n,0,mxCOMPLEX); + } + } + else{ /* for full matrices */ + /* read input */ + in_pr = mxGetPr(prhs[0]); + in_pi = mxGetPr(prhs[0]); + m = mxGetM(prhs[0]); + n = mxGetN(prhs[0]); + thres = mxGetScalar(prhs[1]); + + /* Count new nonzeros */ + newnnz=0; + for(i=0; ithres) {newnnz++;} + } + + if (newnnz>0){ + /* create output */ + plhs[0] = mxCreateSparse(m,n,newnnz,mxCOMPLEX); + if (plhs[0]==NULL) + mexErrMsgTxt("Could not allocate enough memory!\n"); + out_pr = mxGetPr(plhs[0]); + out_pi = mxGetPi(plhs[0]); + out_ir = mxGetIr(plhs[0]); + out_jc = mxGetJc(plhs[0]); + passed = 0; + out_jc[0] = 0; + + for (col=0; col thres){ + + out_pr[passed]=in_pr[current_row_index+m*col]; + out_ir[passed]=current_row_index; + out_jc[col+1] = out_jc[col+1]+1; + passed++; + } + } + } + } + else{ + plhs[0] = mxCreateSparse(m,n,0,mxCOMPLEX); + } + } + } + else { + /* Check data type of input argument */ + if (mxIsSparse(prhs[0])){ + + /* read input */ + in_pr = mxGetPr(prhs[0]); + in_ir = mxGetIr(prhs[0]); + in_jc = mxGetJc(prhs[0]); + nzmax = mxGetNzmax(prhs[0]); + n = mxGetN(prhs[0]); + m = mxGetM(prhs[0]); + thres = mxGetScalar(prhs[1]); + + /* Count new nonzeros */ + newnnz=0; + for(i=0; ithres) {newnnz++;} + } + + if (newnnz>0){ + /* create output */ + plhs[0] = mxCreateSparse(m,n,newnnz,mxREAL); + if (plhs[0]==NULL) + mexErrMsgTxt("Could not allocate enough memory!\n"); + out_pr = mxGetPr(plhs[0]); + out_ir = mxGetIr(plhs[0]); + out_jc = mxGetJc(plhs[0]); + passed = 0; + out_jc[0] = 0; + for (col=0; colthres){ + out_pr[passed]=in_pr[current_row_index]; + out_ir[passed]=in_ir[current_row_index]; + out_jc[col+1] = out_jc[col+1]+1; + passed++; + } + } + } + } + } + else{ + plhs[0] = mxCreateSparse(m,n,0,mxREAL); + } + } + else{ /* for full matrices */ + /* read input */ + in_pr = mxGetPr(prhs[0]); + n = mxGetN(prhs[0]); + m = mxGetM(prhs[0]); + thres = mxGetScalar(prhs[1]); + + /* Count new nonzeros */ + newnnz=0; + for(i=0; ithres) {newnnz++;} + } + + if (newnnz>0){ + /* create output */ + plhs[0] = mxCreateSparse(m,n,newnnz,mxREAL); + if (plhs[0]==NULL) + mexErrMsgTxt("Could not allocate enough memory!\n"); + out_pr = mxGetPr(plhs[0]); + out_ir = mxGetIr(plhs[0]); + out_jc = mxGetJc(plhs[0]); + passed = 0; + out_jc[0] = 0; + + for (col=0; colthres){ + out_pr[passed]=in_pr[current_row_index+m*col]; + out_ir[passed]=current_row_index; + out_jc[col+1] = out_jc[col+1]+1; + passed++; + } + } + } + } + else{ + plhs[0] = mxCreateSparse(m,n,0,mxREAL); + } + } + } +} + diff --git a/SD-VBS/common/toolbox/MultiNcut/sparsifyc.dll b/SD-VBS/common/toolbox/MultiNcut/sparsifyc.dll new file mode 100755 index 0000000..cf832a6 Binary files /dev/null and b/SD-VBS/common/toolbox/MultiNcut/sparsifyc.dll differ diff --git a/SD-VBS/common/toolbox/MultiNcut/sparsifyc.mexa64 b/SD-VBS/common/toolbox/MultiNcut/sparsifyc.mexa64 new file mode 100755 index 0000000..2f5ed26 Binary files /dev/null and b/SD-VBS/common/toolbox/MultiNcut/sparsifyc.mexa64 differ diff --git a/SD-VBS/common/toolbox/MultiNcut/sparsifyc.mexglx b/SD-VBS/common/toolbox/MultiNcut/sparsifyc.mexglx new file mode 100755 index 0000000..0ba41b6 Binary files /dev/null and b/SD-VBS/common/toolbox/MultiNcut/sparsifyc.mexglx differ diff --git a/SD-VBS/common/toolbox/MultiNcut/sparsifyc.mexmac b/SD-VBS/common/toolbox/MultiNcut/sparsifyc.mexmac new file mode 100755 index 0000000..caa2306 Binary files /dev/null and b/SD-VBS/common/toolbox/MultiNcut/sparsifyc.mexmac differ diff --git a/SD-VBS/common/toolbox/MultiNcut/spmtimesd.c b/SD-VBS/common/toolbox/MultiNcut/spmtimesd.c new file mode 100755 index 0000000..a98dc0a --- /dev/null +++ b/SD-VBS/common/toolbox/MultiNcut/spmtimesd.c @@ -0,0 +1,141 @@ +/*================================================================ +* spmtimesd.c +* This routine computes a sparse matrix times a diagonal matrix +* whose diagonal entries are stored in a full vector. +* +* Examples: +* spmtimesd(m,d,[]) = diag(d) * m, +* spmtimesd(m,[],d) = m * diag(d) +* spmtimesd(m,d1,d2) = diag(d1) * m * diag(d2) +* m could be complex, but d is assumed real +* +* Stella X. Yu's first MEX function, Nov 9, 2001. + +% test sequence: + +m = 1000; +n = 2000; +a=sparse(rand(m,n)); +d1 = rand(m,1); +d2 = rand(n,1); +tic; b=spmtimesd(a,d1,d2); toc +tic; bb = spdiags(d1,0,m,m) * a * spdiags(d2,0,n,n); toc +e = (bb-b); +max(abs(e(:))) + +*=================================================================*/ + +# include "mex.h" + +void mexFunction( + int nargout, + mxArray *out[], + int nargin, + const mxArray *in[] +) +{ + /* declare variables */ + int i, j, k, m, n, nzmax, cmplx, xm, yn; + int *pir, *pjc, *qir, *qjc; + double *x, *y, *pr, *pi, *qr, *qi; + + /* check argument */ + if (nargin != 3) { + mexErrMsgTxt("Three input arguments required"); + } + if (nargout>1) { + mexErrMsgTxt("Too many output arguments."); + } + if (!(mxIsSparse(in[0]))) { + mexErrMsgTxt("Input argument #1 must be of type sparse"); + } + if ( mxIsSparse(in[1]) || mxIsSparse(in[2]) ) { + mexErrMsgTxt("Input argument #2 & #3 must be of type full"); + } + + /* computation starts */ + m = mxGetM(in[0]); + n = mxGetN(in[0]); + pr = mxGetPr(in[0]); + pi = mxGetPi(in[0]); + pir = mxGetIr(in[0]); + pjc = mxGetJc(in[0]); + + i = mxGetM(in[1]); + j = mxGetN(in[1]); + xm = ((i>j)? i: j); + + i = mxGetM(in[2]); + j = mxGetN(in[2]); + yn = ((i>j)? i: j); + + if ( xm>0 && xm != m) { + mexErrMsgTxt("Row multiplication dimension mismatch."); + } + if ( yn>0 && yn != n) { + mexErrMsgTxt("Column multiplication dimension mismatch."); + } + + + nzmax = mxGetNzmax(in[0]); + cmplx = (pi==NULL ? 0 : 1); + out[0] = mxCreateSparse(m,n,nzmax,cmplx); + if (out[0]==NULL) { + mexErrMsgTxt("Not enough space for the output matrix."); + } + + qr = mxGetPr(out[0]); + qi = mxGetPi(out[0]); + qir = mxGetIr(out[0]); + qjc = mxGetJc(out[0]); + + /* left multiplication */ + x = mxGetPr(in[1]); + if (yn==0) { + for (j=0; j 3) + error('Too many output arguments.') +end + +% Process inputs and do error-checking +if isa(varargin{1},'double') + A = varargin{1}; + Amatrix = 1; +else + A = fcnchk(varargin{1}); + Amatrix = 0; +end + +isrealprob = 1; % isrealprob = isreal(A) & isreal(B) & isreal(sigma) +if Amatrix + isrealprob = isreal(A); +end + +issymA = 0; +if Amatrix + issymA = isequal(A,A'); +end + +if Amatrix + [m,n] = size(A); + if (m ~= n) + error('A must be a square matrix or a function which computes A*x.') + end +else + n = varargin{2}; + nstr = 'Size of problem, ''n'', must be a positive integer.'; + if ~isequal(size(n),[1,1]) | ~isreal(n) + error(nstr) + end + if (round(n) ~= n) + warning('MATLAB:eigs:NonIntegerSize',['%s\n ' ... + 'Rounding input size.'],nstr) + n = round(n); + end + if issparse(n) + n = full(n); + end +end + +Bnotthere = 0; +Bstr = sprintf(['Generalized matrix B must be the same size as A and' ... + ' either a symmetric positive (semi-)definite matrix or' ... + ' its Cholesky factor.']); +if (nargin < (3-Amatrix-Bnotthere)) + B = []; + Bnotthere = 1; +else + Bk = varargin{3-Amatrix-Bnotthere}; + if isempty(Bk) % allow eigs(A,[],k,sigma,opts); + B = Bk; + else + if isequal(size(Bk),[1,1]) & (n ~= 1) + B = []; + k = Bk; + Bnotthere = 1; + else % eigs(9,8,...) assumes A=9, B=8, ... NOT A=9, k=8, ... + B = Bk; + if ~isa(B,'double') | ~isequal(size(B),[n,n]) + error(Bstr) + end + isrealprob = isrealprob & isreal(B); + end + end +end + +if Amatrix & ((nargin - ~Bnotthere)>4) + error('Too many inputs.') +end + +if (nargin < (4-Amatrix-Bnotthere)) + k = min(n,6); +else + k = varargin{4-Amatrix-Bnotthere}; +end + +kstr = ['Number of eigenvalues requested, k, must be a' ... + ' positive integer <= n.']; +if ~isa(k,'double') | ~isequal(size(k),[1,1]) | ~isreal(k) | (k>n) + error(kstr) +end +if issparse(k) + k = full(k); +end +if (round(k) ~= k) + warning('MATLAB:eigs:NonIntegerEigQty',['%s\n ' ... + 'Rounding number of eigenvalues.'],kstr) + k = round(k); +end + +whchstr = sprintf(['Eigenvalue range sigma must be a valid 2-element string.']); +if (nargin < (5-Amatrix-Bnotthere)) + % default: eigs('LM') => ARPACK which='LM', sigma=0 + eigs_sigma = 'LM'; + whch = 'LM'; + sigma = 0; +else + eigs_sigma = varargin{5-Amatrix-Bnotthere}; + if isstr(eigs_sigma) + % eigs(string) => ARPACK which=string, sigma=0 + if ~isequal(size(eigs_sigma),[1,2]) + whchstr = [whchstr sprintf(['\nFor real symmetric A, the choices are ''%s'', ''%s'', ''%s'', ''%s'' or ''%s''.'], ... + 'LM','SM','LA','SA','BE')]; + whchstr = [whchstr sprintf(['\nFor non-symmetric or complex A, the choices are ''%s'', ''%s'', ''%s'', ''%s'', ''%s'' or ''%s''.\n'], ... + 'LM','SM','LR','SR','LI','SI')]; + error(whchstr) + end + eigs_sigma = upper(eigs_sigma); + if isequal(eigs_sigma,'SM') + % eigs('SM') => ARPACK which='LM', sigma=0 + whch = 'LM'; + else + % eigs(string), where string~='SM' => ARPACK which=string, sigma=0 + whch = eigs_sigma; + end + sigma = 0; + else + % eigs(scalar) => ARPACK which='LM', sigma=scalar + if ~isa(eigs_sigma,'double') | ~isequal(size(eigs_sigma),[1,1]) + error('Eigenvalue shift sigma must be a scalar.') + end + sigma = eigs_sigma; + if issparse(sigma) + sigma = full(sigma); + end + isrealprob = isrealprob & isreal(sigma); + whch = 'LM'; + end +end + +tol = eps; % ARPACK's minimum tolerance is eps/2 (DLAMCH's EPS) +maxit = []; +p = []; +info = int32(0); % use a random starting vector +display = 1; +cholB = 0; + +if (nargin >= (6-Amatrix-Bnotthere)) + opts = varargin{6-Amatrix-Bnotthere}; + if ~isa(opts,'struct') + error('Options argument must be a structure.') + end + + if isfield(opts,'issym') & ~Amatrix + issymA = opts.issym; + if (issymA ~= 0) & (issymA ~= 1) + error('opts.issym must be 0 or 1.') + end + end + + if isfield(opts,'isreal') & ~Amatrix + if (opts.isreal ~= 0) & (opts.isreal ~= 1) + error('opts.isreal must be 0 or 1.') + end + isrealprob = isrealprob & opts.isreal; + end + + if ~isempty(B) & (isfield(opts,'cholB') | isfield(opts,'permB')) + if isfield(opts,'cholB') + cholB = opts.cholB; + if (cholB ~= 0) & (cholB ~= 1) + error('opts.cholB must be 0 or 1.') + end + if isfield(opts,'permB') + if issparse(B) & cholB + permB = opts.permB; + if ~isequal(sort(permB),(1:n)) & ... + ~isequal(sort(permB),(1:n)') + error('opts.permB must be a permutation of 1:n.') + end + else + warning('MATLAB:eigs:IgnoredOptionPermB', ... + ['Ignoring opts.permB since B is not its sparse' ... + ' Cholesky factor.']) + end + else + permB = 1:n; + end + end + end + + if isfield(opts,'tol') + if ~isequal(size(opts.tol),[1,1]) | ~isreal(opts.tol) | (opts.tol<=0) + error(['Convergence tolerance opts.tol must be a strictly' ... + ' positive real scalar.']) + else + tol = full(opts.tol); + end + end + + if isfield(opts,'p') + p = opts.p; + pstr = ['Number of basis vectors opts.p must be a positive' ... + ' integer <= n.']; + if ~isequal(size(p),[1,1]) | ~isreal(p) | (p<=0) | (p>n) + error(pstr) + end + if issparse(p) + p = full(p); + end + if (round(p) ~= p) + warning('MATLAB:eigs:NonIntegerVecQty',['%s\n ' ... + 'Rounding number of basis vectors.'],pstr) + p = round(p); + end + end + + if isfield(opts,'maxit') + maxit = opts.maxit; + str = ['Maximum number of iterations opts.maxit must be' ... + ' a positive integer.']; + if ~isequal(size(maxit),[1,1]) | ~isreal(maxit) | (maxit<=0) + error(str) + end + if issparse(maxit) + maxit = full(maxit); + end + if (round(maxit) ~= maxit) + warning('MATLAB:eigs:NonIntegerIterationQty',['%s\n ' ... + 'Rounding number of iterations.'],str) + maxit = round(maxit); + end + end + + if isfield(opts,'v0') + if ~isequal(size(opts.v0),[n,1]) + error('Start vector opts.v0 must be n-by-1.') + end + if isrealprob + if ~isreal(opts.v0) + error(['Start vector opts.v0 must be real for real problems.']) + end + resid = full(opts.v0); + else + resid(1:2:(2*n-1),1) = full(real(opts.v0)); + resid(2:2:2*n,1) = full(imag(opts.v0)); + end + info = int32(1); % use resid as starting vector + end + + if isfield(opts,'disp') + display = opts.disp; + dispstr = 'Diagnostic level opts.disp must be an integer.'; + if (~isequal(size(display),[1,1])) | (~isreal(display)) | (display<0) + error(dispstr) + end + if (round(display) ~= display) + warning('MATLAB:eigs:NonIntegerDiagnosticLevel', ... + '%s\n Rounding diagnostic level.',dispstr) + display = round(display); + end + end + + if isfield(opts,'cheb') + warning('MATLAB:eigs:ObsoleteOptionCheb', ... + ['Ignoring polynomial acceleration opts.cheb' ... + ' (no longer an option).']); + end + if isfield(opts,'stagtol') + warning('MATLAB:eigs:ObsoleteOptionStagtol', ... + ['Ignoring stagnation tolerance opts.stagtol' ... + ' (no longer an option).']); + end + +end + +% Now we know issymA, isrealprob, cholB, and permB + +if isempty(p) + if isrealprob & ~issymA + p = min(max(2*k+1,20),n); + else + p = min(max(2*k,20),n); + end +end +if isempty(maxit) + maxit = max(300,ceil(2*n/max(p,1))); +end +if (info == int32(0)) + if isrealprob + resid = zeros(n,1); + else + resid = zeros(2*n,1); + end +end + +if ~isempty(B) % B must be symmetric (Hermitian) positive (semi-)definite + if cholB + if ~isequal(triu(B),B) + error(Bstr) + end + else + if ~isequal(B,B') + error(Bstr) + end + end +end + +useeig = 0; +if isrealprob & issymA + knstr = sprintf(['For real symmetric problems, must have number' ... + ' of eigenvalues k < n.\n']); +else + knstr = sprintf(['For nonsymmetric and complex problems, must have' ... + ' number of eigenvalues k < n-1.\n']); +end +if isempty(B) + knstr = [knstr sprintf(['Using eig(full(A)) instead.'])]; +else + knstr = [knstr sprintf(['Using eig(full(A),full(B)) instead.'])]; +end +if (k == 0) + useeig = 1; +end +if isrealprob & issymA + if (k > n-1) + if (n >= 6) + warning('MATLAB:eigs:TooManyRequestedEigsForRealSym', ... + '%s',knstr) + end + useeig = 1; + end +else + if (k > n-2) + if (n >= 7) + warning('MATLAB:eigs:TooManyRequestedEigsForComplexNonsym', ... + '%s',knstr) + end + useeig = 1; + end +end + +if isrealprob & issymA + if ~isreal(sigma) + error(['For real symmetric problems, eigenvalue shift sigma must' ... + ' be real.']) + end +else + if ~isrealprob & issymA & ~isreal(sigma) + warning('MATLAB:eigs:ComplexShiftForRealProblem', ... + ['Complex eigenvalue shift sigma on a Hermitian problem' ... + ' (all real eigenvalues).']) + end +end + +if isrealprob & issymA + if strcmp(whch,'LR') + whch = 'LA'; + warning('MATLAB:eigs:SigmaChangedToLA', ... + ['For real symmetric problems, sigma value ''LR''' ... + ' (Largest Real) is now ''LA'' (Largest Algebraic).']) + end + if strcmp(whch,'SR') + whch = 'SA'; + warning('MATLAB:eigs:SigmaChangedToSA', ... + ['For real symmetric problems, sigma value ''SR''' ... + ' (Smallest Real) is now ''SA'' (Smallest Algebraic).']) + end + if ~ismember(whch,{'LM', 'SM', 'LA', 'SA', 'BE'}) + whchstr = [whchstr sprintf(['\nFor real symmetric A, the choices are ''%s'', ''%s'', ''%s'', ''%s'' or ''%s''.'], ... + 'LM','SM','LA','SA','BE')]; + error(whchstr) + end +else + if strcmp(whch,'BE') + warning('MATLAB:eigs:SigmaChangedToLM', ... + ['Sigma value ''BE'' is now only available for real' ... + ' symmetric problems. Computing ''LM'' eigenvalues instead.']) + whch = 'LM'; + end + if ~ismember(whch,{'LM', 'SM', 'LR', 'SR', 'LI', 'SI'}) + whchstr = [whchstr sprintf(['\nFor non-symmetric or complex A, the choices are ''%s'', ''%s'', ''%s'', ''%s'', ''%s'' or ''%s''.\n'], ... + 'LM','SM','LR','SR','LI','SI')]; + error(whchstr) + end +end + +% Now have enough information to do early return on cases eigs does not handle +if useeig + if (nargout <= 1) + varargout{1} = eigs2(A,n,B,k,whch,sigma,cholB, ... + varargin{7-Amatrix-Bnotthere:end}); + else + [varargout{1},varargout{2}] = eigs2(A,n,B,k,whch,sigma,cholB, ... + varargin{7-Amatrix-Bnotthere:end}); + end + if (nargout == 3) + varargout{3} = 0; % flag indicates "convergence" + end + return +end + +if isrealprob & ~issymA + sigmar = real(sigma); + sigmai = imag(sigma); +end + +if isrealprob & issymA + if (p <= k) + error(['For real symmetric problems, must have number of' ... + ' basis vectors opts.p > k.']) + end +else + if (p <= k+1) + error(['For nonsymmetric and complex problems, must have number of' ... + ' basis vectors opts.p > k+1.']) + end +end + +if isequal(whch,'LM') & ~isequal(eigs_sigma,'LM') + % A*x = lambda*M*x, M symmetric (positive) semi-definite + % => OP = inv(A - sigma*M)*M and B = M + % => shift-and-invert mode + mode = 3; +elseif isempty(B) + % A*x = lambda*x + % => OP = A and B = I + mode = 1; +else % B is not empty + % Do not use mode=2. + % Use mode = 1 with OP = R'\(A*(R\x)) and B = I + % where R is B's upper triangular Cholesky factor: B = R'*R. + % Finally, V = R\V returns the actual generalized eigenvectors of A and B. + mode = 1; +end + +if cholB + pB = 0; + RB = B; + RBT = B'; +end + +if (mode == 3) & Amatrix % need lu(A-sigma*B) + if issparse(A) & (isempty(B) | issparse(B)) + if isempty(B) + AsB = A - sigma * speye(n); + else + if cholB + AsB = A - sigma * RBT * RB; + else + AsB = A - sigma * B; + end + end + [L,U,P,Q] = lu(AsB); + [perm,dummy] = find(Q); + else + if isempty(B) + AsB = A - sigma * eye(n); + else + if cholB + AsB = A - sigma * RBT * RB; + else + AsB = A - sigma * B; + end + end + [L,U,P] = lu(AsB); + end + dU = diag(U); + rcondestU = full(min(abs(dU)) / max(abs(dU))); + if (rcondestU < eps) + if isempty(B) + ds = sprintf(['(A-sigma*I) has small reciprocal condition' ... + ' estimate: %f\n'],rcondestU); + else + ds = sprintf(['(A-sigma*B) has small reciprocal condition' ... + ' estimate: %f\n'],rcondestU); + end + ds = [ds sprintf(['indicating that sigma is near an exact' ... + ' eigenvalue. The\nalgorithm may not converge unless' ... + ' you try a new value for sigma.\n'])]; + warning('MATLAB:eigs:SigmaNearExactEig',ds) + end +end + +if (mode == 1) & ~isempty(B) & ~cholB % need chol(B) + if issparse(B) + permB = symamd(B); + [RB,pB] = chol(B(permB,permB)); + else + [RB,pB] = chol(B); + end + if (pB == 0) + RBT = RB'; + else + error(Bstr) + end +end + +% Allocate outputs and ARPACK work variables +if isrealprob + if issymA % real and symmetric + prefix = 'ds'; + v = zeros(n,p); + ldv = int32(size(v,1)); + ipntr = int32(zeros(15,1)); + workd = zeros(n,3); + lworkl = p*(p+8); + workl = zeros(lworkl,1); + lworkl = int32(lworkl); + d = zeros(k,1); + else % real but not symmetric + prefix = 'dn'; + v = zeros(n,p); + ldv = int32(size(v,1)); + ipntr = int32(zeros(15,1)); + workd = zeros(n,3); + lworkl = 3*p*(p+2); + workl = zeros(lworkl,1); + lworkl = int32(lworkl); + workev = zeros(3*p,1); + d = zeros(k+1,1); + di = zeros(k+1,1); + end +else % complex + prefix = 'zn'; + zv = zeros(2*n*p,1); + ldv = int32(n); + ipntr = int32(zeros(15,1)); + workd = complex(zeros(n,3)); + zworkd = zeros(2*prod(size(workd)),1); + lworkl = 3*p^2+5*p; + workl = zeros(2*lworkl,1); + lworkl = int32(lworkl); + workev = zeros(2*2*p,1); + zd = zeros(2*(k+1),1); + rwork = zeros(p,1); +end + +ido = int32(0); % reverse communication parameter +if isempty(B) | (~isempty(B) & (mode == 1)) + bmat = 'I'; % standard eigenvalue problem +else + bmat = 'G'; % generalized eigenvalue problem +end +nev = int32(k); % number of eigenvalues requested +ncv = int32(p); % number of Lanczos vectors +iparam = int32(zeros(11,1)); +iparam([1 3 7]) = int32([1 maxit mode]); +select = int32(zeros(p,1)); + +cputms(1) = cputime - t0; % end timing pre-processing + +iter = 0; +ariter = 0; + + +%tim + + +indexArgumentsAfun = 7-Amatrix-Bnotthere:length(varargin); +nbArgumentsAfun = length(indexArgumentsAfun); +if nbArgumentsAfun >=1 + arguments_Afun = varargin{7-Amatrix-Bnotthere}; +end +if nbArgumentsAfun >=2 + arguments_Afun2 = varargin{7-Amatrix-Bnotthere+1}; +end +if nbArgumentsAfun >=3 + arguments_Afun3 = varargin{7-Amatrix-Bnotthere+2}; +end +%fin tim + + + +while (ido ~= 99) + + t0 = cputime; % start timing ARPACK calls **aupd + + if isrealprob + arpackc( [prefix 'aupd'], ido, ... + bmat, int32(n), whch, nev, tol, resid, ncv, ... + v, ldv, iparam, ipntr, workd, workl, lworkl, info); + else + zworkd(1:2:end-1) = real(workd); + zworkd(2:2:end) = imag(workd); + arpackc( 'znaupd', ido, ... + bmat, int32(n), whch, nev, tol, resid, ncv, zv, ... + ldv, iparam, ipntr, zworkd, workl, lworkl, ... + rwork, info ); + workd = reshape(complex(zworkd(1:2:end-1),zworkd(2:2:end)),[n,3]); + end + + if (info < 0) + es = sprintf('Error with ARPACK routine %saupd: info = %d',... + prefix,full(info)); + error(es) + end + + cputms(2) = cputms(2) + (cputime-t0); % end timing ARPACK calls **aupd + t0 = cputime; % start timing MATLAB OP(X) + + % Compute which columns of workd ipntr references + + + + + + %[row,col1] = ind2sub([n,3],double(ipntr(1))); + %tim + row = mod(double(ipntr(1))-1,n) + 1 ; + col1 = floor((double(ipntr(1))-1)/n) + 1; + + + if (row ~= 1) + str = sprintf(['ipntr(1)=%d does not refer to the start of a' ... + ' column of the %d-by-3 array workd.'],full(ipntr(1)),n); + error(str) + end + + + + %[row,col2] = ind2sub([n,3],double(ipntr(2))); + %tim + row = mod(double(ipntr(2))-1,n) + 1 ; + col2 = floor((double(ipntr(2))-1)/n) + 1; + + + + if (row ~= 1) + str = sprintf(['ipntr(2)=%d does not refer to the start of a' ... + ' column of the %d-by-3 array workd.'],full(ipntr(2)),n); + error(str) + end + if ~isempty(B) & (mode == 3) & (ido == 1) + [row,col3] = ind2sub([n,3],double(ipntr(3))); + if (row ~= 1) + str = sprintf(['ipntr(3)=%d does not refer to the start of a' ... + ' column of the %d-by-3 array workd.'],full(ipntr(3)),n); + error(str) + end + end + + switch (ido) + case {-1,1} + if Amatrix + if (mode == 1) + if isempty(B) + % OP = A*x + workd(:,col2) = A * workd(:,col1); + else + % OP = R'\(A*(R\x)) + if issparse(B) + workd(permB,col2) = RB \ workd(:,col1); + workd(:,col2) = A * workd(:,col2); + workd(:,col2) = RBT \ workd(permB,col2); + else + workd(:,col2) = RBT \ (A * (RB \ workd(:,col1))); + end + end + elseif (mode == 3) + if isempty(B) + if issparse(A) + workd(perm,col2) = U \ (L \ (P * workd(:,col1))); + else + workd(:,col2) = U \ (L \ (P * workd(:,col1))); + end + else % B is not empty + if (ido == -1) + if cholB + workd(:,col2) = RBT * (RB * workd(:,col1)); + else + workd(:,col2) = B * workd(:,col1); + end + if issparse(A) & issparse(B) + workd(perm,col2) = U \ (L \ (P * workd(:,col1))); + else + workd(:,col2) = U \ (L \ (P * workd(:,col1))); + end + elseif (ido == 1) + if issparse(A) & issparse(B) + workd(perm,col2) = U \ (L \ (P * workd(:,col3))); + else + workd(:,col2) = U \ (L \ (P * workd(:,col3))); + end + end + end + else % mode is not 1 or 3 + error(['Unknown mode returned from ' prefix 'aupd.']) + end + else % A is not a matrix + if (mode == 1) + if isempty(B) + % OP = A*x + %workd(:,col2) = feval(A,workd(:,col1),varargin{7-Amatrix-Bnotthere:end}); + + + + + + nombre_A_times_X = nombre_A_times_X + 1; + + + + pause(0); %voir + + if nbArgumentsAfun == 1 + workd(:,col2) = feval(A,workd(:,col1),arguments_Afun); + %workd(:,col2) = max(workd(:,col2),0); + elseif nbArgumentsAfun == 2 + workd(:,col2) = feval(A,workd(:,col1),arguments_Afun,arguments_Afun2); + elseif nbArgumentsAfun == 3 + workd(:,col2) = feval(A,workd(:,col1),arguments_Afun,arguments_Afun2,arguments_Afun3); + else + workd(:,col2) = feval(A,workd(:,col1),varargin{indexArgumentsAfun}); + end + %workd(:,col2) = tim_w_times_x_c(workd(:,col1),arguments_Afun); %slower + + else + % OP = R'\(A*(R\x)) + if issparse(B) + workd(permB,col2) = RB \ workd(:,col1); + workd(:,col2) = feval(A,workd(:,col2),arguments_Afun); + workd(:,col2) = RBT \ workd(permB,col2); + + else + workd(:,col2) = RBT \ feval(A,(RB\workd(:,col1)),arguments_Afun); + end + end + elseif (mode == 3) + if isempty(B) + workd(:,col2) = feval(A,workd(:,col1), arguments_Afun); + else + if (ido == -1) + if cholB + workd(:,col2) = RBT * (RB * workd(:,col1)); + else + workd(:,col2) = B * workd(:,col1); + end + workd(:,col2) = feval(A,workd(:,col2), arguments_Afun); + elseif (ido == 1) + workd(:,col2) = feval(A,workd(:,col3), arguments_Afun); + end + end + else % mode is not 1 or 3 + error(['Unknown mode returned from ' prefix 'aupd.']) + end + end % if Amatrix + case 2 + if (mode == 3) + if cholB + workd(:,col2) = RBT * (RB * workd(:,col1)); + else + workd(:,col2) = B * workd(:,col1); + end + else + error(['Unknown mode returned from ' prefix 'aupd.']) + end + case 3 + % setting iparam(1) = ishift = 1 ensures this never happens + warning('MATLAB:eigs:WorklShiftsUnsupported', ... + ['EIGS does not yet support computing the shifts in workl.' ... + ' Setting reverse communication parameter to 99 and returning.']) + ido = int32(99); + case 99 + otherwise + error(['Unknown value of reverse communication parameter' ... + ' returned from ' prefix 'aupd.']) + end + + cputms(3) = cputms(3) + (cputime-t0); % end timing MATLAB OP(X) + + %tim + if nombreIterations ~= double(ipntr(15)) + nombreIterations = double(ipntr(15)); + end + + if display >= 1 && display <=2 + iter = double(ipntr(15)); + if (iter > ariter) & (ido ~= 99) + ariter = iter; + ds = sprintf(['Iteration %d: a few Ritz values of the' ... + ' %d-by-%d matrix:'],iter,p,p); + disp(ds) + if isrealprob + if issymA + dispvec = [workl(double(ipntr(6))+(0:p-1))]; + if isequal(whch,'BE') + % roughly k Large eigenvalues and k Small eigenvalues + disp(dispvec(max(end-2*k+1,1):end)) + else + % k eigenvalues + disp(dispvec(max(end-k+1,1):end)) + end + else + dispvec = [complex(workl(double(ipntr(6))+(0:p-1)), ... + workl(double(ipntr(7))+(0:p-1)))]; + % k+1 eigenvalues (keep complex conjugate pairs together) + disp(dispvec(max(end-k,1):end)) + end + else + dispvec = [complex(workl(2*double(ipntr(6))-1+(0:2:2*(p-1))), ... + workl(2*double(ipntr(6))+(0:2:2*(p-1))))]; + disp(dispvec(max(end-k+1,1):end)) + end + end + end + +end % while (ido ~= 99) + +t0 = cputime; % start timing post-processing + +flag = 0; +if (info < 0) + es = sprintf('Error with ARPACK routine %saupd: info = %d',prefix,full(info)); + error(es) +else + if (nargout >= 2) + rvec = int32(1); % compute eigenvectors + else + rvec = int32(0); % do not compute eigenvectors + end + + if isrealprob + if issymA + arpackc( 'dseupd', rvec, 'A', select, ... + d, v, ldv, sigma, ... + bmat, int32(n), whch, nev, tol, resid, ncv, ... + v, ldv, iparam, ipntr, workd, workl, lworkl, info ); + if isequal(whch,'LM') | isequal(whch,'LA') + d = flipud(d); + if (rvec == 1) + v(:,1:k) = v(:,k:-1:1); + end + end + if ((isequal(whch,'SM') | isequal(whch,'SA')) & (rvec == 0)) + d = flipud(d); + end + else + arpackc( 'dneupd', rvec, 'A', select, ... + d, di, v, ldv, sigmar, sigmai, workev, ... + bmat, int32(n), whch, nev, tol, resid, ncv, ... + v, ldv, iparam, ipntr, workd, workl, lworkl, info ); + d = complex(d,di); + if rvec + d(k+1) = []; + else + zind = find(d == 0); + if isempty(zind) + d = d(k+1:-1:2); + else + d(max(zind)) = []; + d = flipud(d); + end + end + end + else + zsigma = [real(sigma); imag(sigma)]; + arpackc( 'zneupd', rvec, 'A', select, ... + zd, zv, ldv, zsigma, workev, ... + bmat, int32(n), whch, nev, tol, resid, ncv, zv, ... + ldv, iparam, ipntr, zworkd, workl, lworkl, ... + rwork, info ); + if issymA + d = zd(1:2:end-1); + else + d = complex(zd(1:2:end-1),zd(2:2:end)); + end + v = reshape(complex(zv(1:2:end-1),zv(2:2:end)),[n p]); + end + + if (info ~= 0) + es = ['Error with ARPACK routine ' prefix 'eupd: ']; + switch double(info) + case 2 + ss = sum(select); + if (ss < k) + es = [es ... + ' The logical variable select was only set with ' int2str(ss) ... + ' 1''s instead of nconv=' int2str(double(iparam(5))) ... + ' (k=' int2str(k) ').' ... + ' Please contact the ARPACK authors at arpack@caam.rice.edu.']; + else + es = [es ... + 'The LAPACK reordering routine ' prefix(1) ... + 'trsen did not return all ' int2str(k) ' eigenvalues.'] + end + case 1 + es = [es ... + 'The Schur form could not be reordered by the LAPACK routine ' ... + prefix(1) 'trsen.' ... + ' Please contact the ARPACK authors at arpack@caam.rice.edu.']; + case -14 + es = [es prefix ... + 'aupd did not find any eigenvalues to sufficient accuracy.']; + otherwise + es = [es sprintf('info = %d',full(info))]; + end + error(es) + else + nconv = double(iparam(5)); + if (nconv == 0) + if (nargout < 3) + warning('MATLAB:eigs:NoEigsConverged', ... + 'None of the %d requested eigenvalues converged.',k) + else + flag = 1; + end + elseif (nconv < k) + if (nargout < 3) + warning('MATLAB:eigs:NotAllEigsConverged', ... + 'Only %d of the %d requested eigenvalues converged.',nconv,k) + else + flag = 1; + end + end + end % if (info ~= 0) +end % if (info < 0) + +if (issymA) | (~isrealprob) + if (nargout <= 1) + if isrealprob + varargout{1} = d; + else + varargout{1} = d(k:-1:1,1); + end + else + varargout{1} = v(:,1:k); + varargout{2} = diag(d(1:k,1)); + if (nargout >= 3) + varargout{3} = flag; + end + end +else + if (nargout <= 1) + varargout{1} = d; + else + cplxd = find(di ~= 0); + % complex conjugate pairs of eigenvalues occur together + cplxd = cplxd(1:2:end); + v(:,[cplxd cplxd+1]) = [complex(v(:,cplxd),v(:,cplxd+1)) ... + complex(v(:,cplxd),-v(:,cplxd+1))]; + varargout{1} = v(:,1:k); + varargout{2} = diag(d); + if (nargout >= 3) + varargout{3} = flag; + end + end +end + +if (nargout >= 2) & (mode == 1) & ~isempty(B) + if issparse(B) + varargout{1}(permB,:) = RB \ varargout{1}; + else + varargout{1} = RB \ varargout{1}; + end +end + +cputms(4) = cputime-t0; % end timing post-processing + +cputms(5) = sum(cputms(1:4)); % total time + +if (display >= 2) %tim + if (mode == 1) + innerstr = sprintf(['Compute A*X:' ... + ' %f\n'],cputms(3)); + elseif (mode == 2) + innerstr = sprintf(['Compute A*X and solve B*X=Y for X:' ... + ' %f\n'],cputms(3)); + elseif (mode == 3) + if isempty(B) + innerstr = sprintf(['Solve (A-SIGMA*I)*X=Y for X:' ... + ' %f\n'],cputms(3)); + else + innerstr = sprintf(['Solve (A-SIGMA*B)*X=B*Y for X:' ... + ' %f\n'],cputms(3)); + end + end + if ((mode == 3) & (Amatrix)) + if isempty(B) + prepstr = sprintf(['Pre-processing, including lu(A-sigma*I):' ... + ' %f\n'],cputms(1)); + else + prepstr = sprintf(['Pre-processing, including lu(A-sigma*B):' ... + ' %f\n'],cputms(1)); + end + elseif ((mode == 2) & (~cholB)) + prepstr = sprintf(['Pre-processing, including chol(B):' ... + ' %f\n'],cputms(1)); + else + prepstr = sprintf(['Pre-processing:' ... + ' %f\n'],cputms(1)); + end + sstr = sprintf(['***********CPU Timing Results in seconds***********']); + ds = sprintf(['\n' sstr '\n' ... + prepstr ... + 'ARPACK''s %saupd: %f\n' ... + innerstr ... + 'Post-processing with ARPACK''s %seupd: %f\n' ... + '***************************************************\n' ... + 'Total: %f\n' ... + sstr '\n'], ... + prefix,cputms(2),prefix,cputms(4),cputms(5)); + disp(ds) + if nombre_A_times_X > 0 %tim + disp(sprintf('Number of iterations : %f\n',nombreIterations)); + disp(sprintf('Number of times A*X was computed : %f\n',nombre_A_times_X)); + disp(sprintf('Average time for A*X : %f\n',cputms(3)/nombre_A_times_X)); + end +end diff --git a/SD-VBS/common/toolbox/ikkjin/getANMS.m b/SD-VBS/common/toolbox/ikkjin/getANMS.m new file mode 100755 index 0000000..a40d50c --- /dev/null +++ b/SD-VBS/common/toolbox/ikkjin/getANMS.m @@ -0,0 +1,30 @@ +function [interestPnts]=getANMS(x, y, v, r, dataDir) +MAX_LIMIT=100000; +C_ROBUST=1; +r_sq=r^2; +points=[x y v]; +[n temp]=size(v); +[srtdV srtdVIdx]=sort(v,'descend'); +srtdPnts=points(srtdVIdx,:); + +interestPnts=zeros(0,3); + +suppressR=ones(n,1)*MAX_LIMIT; +supId=find(suppressR>r_sq); + +iter = 0; +while length(supId)>0 + + interestPnts=[interestPnts; srtdPnts(supId(1),:)]; + srtdPnts=srtdPnts(supId(2:end),:); + suppressR=suppressR(supId(2:end),:); + + suppressR=min(suppressR,... + (C_ROBUST*interestPnts(end,3)>=srtdPnts(:,3)).*... + ((srtdPnts(:,1)-interestPnts(end,1)).^2 + (srtdPnts(:,2)-interestPnts(end,2)).^2)... + +(C_ROBUST*interestPnts(end,3)r_sq); +end diff --git a/SD-VBS/common/toolbox/ikkjin/getImgGrad.m b/SD-VBS/common/toolbox/ikkjin/getImgGrad.m new file mode 100755 index 0000000..90fae28 --- /dev/null +++ b/SD-VBS/common/toolbox/ikkjin/getImgGrad.m @@ -0,0 +1,7 @@ +function Ig=getImgGrad(imgroi) +im = double(rgb2gray(imgroi)); +g1 = fspecial('gaussian', 9,1); % Gaussian with sigma_d +img1 = conv2(im,g1,'same'); % blur image with sigma_d +Ix = conv2(img1,[-1 0 1],'same'); % take x derivative +Iy = conv2(img1,[-1;0;1],'same'); % take y derivative +Ig=Ix.^2+Iy.^2; \ No newline at end of file diff --git a/SD-VBS/common/toolbox/ikkjin/harris.m b/SD-VBS/common/toolbox/ikkjin/harris.m new file mode 100755 index 0000000..92a6543 --- /dev/null +++ b/SD-VBS/common/toolbox/ikkjin/harris.m @@ -0,0 +1,43 @@ + +% Sample code for detecting Harris corners, following +% Brown et al, CVPR 2005 +% by Alyosha Efros, so probably buggy... +% slightly modified by ikkjin + +function [x,y,v] = harris(imrgb); +[nr nc nb]=size(imrgb); +if nb==3 + im=rgb2gray(imrgb); +else + im=imrgb; +end + +im = im2double(im); +g1 = fspecial('gaussian', 9,1); % Gaussian with sigma_d +g2 = fspecial('gaussian', 11,1.5); % Gaussian with sigma_i +img1 = conv2(im,g1,'same'); % blur image with sigma_d +Ix = conv2(img1,[-1 0 1],'same'); % take x derivative +Iy = conv2(img1,[-1;0;1],'same'); % take y derivative + +% Compute elements of the Harris matrix H +%%% we can use blur instead of the summing window +Ix2 = conv2(Ix.*Ix,g2,'same'); +Iy2 = conv2(Iy.*Iy,g2,'same'); +IxIy = conv2(Ix.*Iy,g2,'same'); +R = (Ix2.*Iy2 - IxIy.*IxIy) ... % det(H) + ./ (Ix2 + Iy2 + eps); % trace(H) + epsilon + +% don't want corners close to image border +R([1:15, end-16:end], :) = 0; +R(:,[1:15,end-16:end]) = 0; + +% non-maxima supression within 3x3 windows +nonmax = inline('max(x)'); +Rmax = colfilt(R,[3 3],'sliding',nonmax); % find neighbrhood max +Rnm = R.*(R == Rmax); % supress non-max + +% extract all interest points +[y,x,v] = find(Rnm); + + + diff --git a/SD-VBS/common/toolbox/lagrcv/Makefile b/SD-VBS/common/toolbox/lagrcv/Makefile new file mode 100755 index 0000000..af7e8f5 --- /dev/null +++ b/SD-VBS/common/toolbox/lagrcv/Makefile @@ -0,0 +1,21 @@ +rm liblagrcv.a +gcc -c -fPIC lagrcv.cpp +ar rc liblagrcv.a lagrcv.o +ranlib liblagrcv.a + +mex -O calcSubsampleAvgMex.cc -L/u/ikkjin/Matlab/Toolbox/lagrcv -llagrcv -I/u/ikkjin/Matlab/Toolbox/lagrcv/ +mex -O calcSobelMex.cc -L/u/ikkjin/Matlab/Toolbox/lagrcv -llagrcv -I/u/ikkjin/Matlab/Toolbox/lagrcv/ +mex -O calcImgBlurMex.cc -L/u/ikkjin/Matlab/Toolbox/lagrcv -llagrcv -I/u/ikkjin/Matlab/Toolbox/lagrcv/ +mex -O calcOptFlowLKMex.cc -L/u/ikkjin/Matlab/Toolbox/lagrcv -llagrcv -I/u/ikkjin/Matlab/Toolbox/lagrcv/ +mex -O calcResizedImgMex.cc -L/u/ikkjin/Matlab/Toolbox/lagrcv -llagrcv -I/u/ikkjin/Matlab/Toolbox/lagrcv/ +mex -O calcTextureMex.cc -L/u/ikkjin/Matlab/Toolbox/lagrcv -llagrcv -I/u/ikkjin/Matlab/Toolbox/lagrcv/ +mex -O calcGradientPyrMex.cc -L/u/ikkjin/Matlab/Toolbox/lagrcv -llagrcv -I/u/ikkjin/Matlab/Toolbox/lagrcv/ +mex -O calcSobelPyrMex.cc -L/u/ikkjin/Matlab/Toolbox/lagrcv -llagrcv -I/u/ikkjin/Matlab/Toolbox/lagrcv/ +mex -O calcTexturePyrMex.cc -L/u/ikkjin/Matlab/Toolbox/lagrcv -llagrcv -I/u/ikkjin/Matlab/Toolbox/lagrcv/ +mex -O calcOptFlowLKPyrMex.cc -L/u/ikkjin/Matlab/Toolbox/lagrcv -llagrcv -I/u/ikkjin/Matlab/Toolbox/lagrcv/ +mex -O calcOptFlowLKPyrMex2.cc -L/u/ikkjin/Matlab/Toolbox/lagrcv -llagrcv -I/u/ikkjin/Matlab/Toolbox/lagrcv/ +mex -O calcOptFlowLKPyrWInitMex2.cc -L/u/ikkjin/Matlab/Toolbox/lagrcv -llagrcv -I/u/ikkjin/Matlab/Toolbox/lagrcv/ +mex -O calcOptFlowLKPyrWInitMex.cc -L/u/ikkjin/Matlab/Toolbox/lagrcv -llagrcv -I/u/ikkjin/Matlab/Toolbox/lagrcv/ +mex -O calcOptFlowLKPyrWInitSobelMex.cc -L/u/ikkjin/Matlab/Toolbox/lagrcv -llagrcv -I/u/ikkjin/Matlab/Toolbox/lagrcv/ +mex -O dummyMex.cc -L/u/ikkjin/Matlab/Toolbox/lagrcv -llagrcv -I/u/ikkjin/Matlab/Toolbox/lagrcv/ + diff --git a/SD-VBS/common/toolbox/lagrcv/README.sxw b/SD-VBS/common/toolbox/lagrcv/README.sxw new file mode 100755 index 0000000..9f20d14 Binary files /dev/null and b/SD-VBS/common/toolbox/lagrcv/README.sxw differ diff --git a/SD-VBS/common/toolbox/lagrcv/calcGradientPyrMex.cc b/SD-VBS/common/toolbox/lagrcv/calcGradientPyrMex.cc new file mode 100755 index 0000000..d94130b --- /dev/null +++ b/SD-VBS/common/toolbox/lagrcv/calcGradientPyrMex.cc @@ -0,0 +1,45 @@ + +/* compile with +rm liblagrcv.a +gcc -c lagrcv.cpp +ar rc liblagrcv.a lagrcv.o +ranlib liblagrcv.a +mex7 calcTextureMex.cc -L/home/ikkjin/LagrMatlab/opencv/matlab -llagrcv -I/home/ikkjin/LagrMatlab/opencv/matlab/ +*/ + +#include "mex.h" +#include "lagrcv.h" +#include +#include + +// TODO: add number of corners parameter +void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { + // usage: [dxPye dyPyr] = + // calcGradientPyrMex(imagePyr) + + const int *cellDims = mxGetDimensions(prhs[0]); + double *image; + const mxArray* imgArray; + mxArray *dxArray, *dyArray; + double *dx, *dy; + const int *imdims; + + plhs[0] = mxCreateCellArray(1, cellDims); + plhs[1] = mxCreateCellArray(1, cellDims); + + for(int i=0; i +#include + +// TODO: add number of corners parameter +void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { + // usage: [IBlur] = + // calcImgBlurMex(image) + + double *image, *retImg; + const int *imdims; + + image=(double*)mxGetPr(prhs[0]); + imdims = mxGetDimensions(prhs[0]); + + plhs[0] = mxCreateNumericMatrix(imdims[0], imdims[1], mxDOUBLE_CLASS, mxREAL); + retImg=(double*)mxGetPr(plhs[0]); + + calcImgBlur(image, imdims[0], imdims[1], retImg); +} diff --git a/SD-VBS/common/toolbox/lagrcv/calcImgBlurMex.mexa64 b/SD-VBS/common/toolbox/lagrcv/calcImgBlurMex.mexa64 new file mode 100755 index 0000000..8f4bfea Binary files /dev/null and b/SD-VBS/common/toolbox/lagrcv/calcImgBlurMex.mexa64 differ diff --git a/SD-VBS/common/toolbox/lagrcv/calcImgBlurMex.mexglx b/SD-VBS/common/toolbox/lagrcv/calcImgBlurMex.mexglx new file mode 100755 index 0000000..ade786d Binary files /dev/null and b/SD-VBS/common/toolbox/lagrcv/calcImgBlurMex.mexglx differ diff --git a/SD-VBS/common/toolbox/lagrcv/calcOptFlowLKMex.cc b/SD-VBS/common/toolbox/lagrcv/calcOptFlowLKMex.cc new file mode 100755 index 0000000..e22af8b --- /dev/null +++ b/SD-VBS/common/toolbox/lagrcv/calcOptFlowLKMex.cc @@ -0,0 +1,85 @@ + +/* compile with +rm liblagrcv.a +gcc -c lagrcv.cpp +ar rc liblagrcv.a lagrcv.o +ranlib liblagrcv.a +mex7 calcTextureMex.cc -L/home/ikkjin/LagrMatlab/opencv/matlab -llagrcv -I/home/ikkjin/LagrMatlab/opencv/matlab/ +*/ + +#include "mex.h" +#include "lagrcv.h" +#include +#include + +#ifndef MAX_LEVEL +# define MAX_LEVEL 5 +#endif +// TODO: add number of corners parameter +void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { + // usage: [newFeaturePnt validFlag ] = + // calcOptFlowLKMex(I, Idx, Idy, J, c_xx, c_xy, c_yy, featurePnt, initialPnt, winSize, accuracy_th, max_iter) + // featurePnt 2xn int + // winSize c_level int + // c_xx c_xy c_yy: image size double* + // image must be double + + + const int* imdims; + const int *nFeatures; + double *imgI, *iDx, *iDy, *imgJ, *c_xx, *c_xy, *c_yy; + double *fPnt, *initPnt, *newFPnt; + char* valid; + double accuracy_th; + int winSize, max_iter; + + if (nrhs > 10) { + accuracy_th=(double)mxGetScalar(prhs[10]); + max_iter=(int)mxGetScalar(prhs[11]); + } + + winSize = (int)mxGetScalar(prhs[9]); + initPnt=(double*)mxGetPr(prhs[8]); + fPnt=(double*)mxGetPr(prhs[7]); + c_xx=(double*)mxGetPr(prhs[6]); + c_xy=(double*)mxGetPr(prhs[5]); + c_yy=(double*)mxGetPr(prhs[4]); + imgJ=(double*)mxGetPr(prhs[3]); + iDy=(double*)mxGetPr(prhs[2]); + iDx=(double*)mxGetPr(prhs[1]); + imgI=(double*)mxGetPr(prhs[0]); + nFeatures=mxGetDimensions(prhs[7]); + imdims=mxGetDimensions(prhs[0]); + + plhs[0] = mxCreateNumericMatrix(nFeatures[0], nFeatures[1], mxDOUBLE_CLASS, mxREAL); + plhs[1] = mxCreateNumericMatrix(1, nFeatures[1], mxUINT8_CLASS, mxREAL); + + newFPnt = (double*)mxGetPr(plhs[0]); + valid = (char*)mxGetPr(plhs[1]); + + //idx convert from matlab to c + for(int i=0; i10){ + calcLKTrack( imgI, iDx, iDy, imgJ, imdims, + c_xx, c_xy, c_yy, + fPnt, initPnt, nFeatures[1], winSize, + newFPnt, valid, accuracy_th, max_iter); + }else{ + calcLKTrack( imgI, iDx, iDy, imgJ, imdims, + c_xx, c_xy, c_yy, + fPnt, initPnt, nFeatures[1], winSize, + newFPnt, valid); + } + //idx convert from matlab to c + for(int i=0; i +#include + +#ifndef MAX_LEVEL +# define MAX_LEVEL 5 +#endif +// TODO: add number of corners parameter +void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { + // usage: [newFeaturePnt validFlag ] = + // calcOptFlowPyrLKMex(Ipyr, IdxPyr, IdyPyr, Jpyr, featurePnt, winSize, accuracy_th, max_iter) + // Ipyr, IdxPyr, IdyPyr, Jpyr: levelx1 size cell. + // featurePnt 2xn int + // winSize c_level int + // c_xx c_xy c_yy: image size double* + // image must be double + + + const mxArray* imgArray; + int* imdims; + const int *curImgDims; + const int *nFeatures; + //double **iP, **iDxP, **iDyP, **jP; + double *iP[MAX_LEVEL], *iDxP[MAX_LEVEL], *iDyP[MAX_LEVEL], *jP[MAX_LEVEL]; + double *fPnt, *newFPnt; + char* valid; + double accuracy_th; + int winSize, max_iter; + const int *cellDims = mxGetDimensions(prhs[0]); + + if (nrhs > 6) { + accuracy_th=(double)mxGetScalar(prhs[6]); + max_iter=(int)mxGetScalar(prhs[7]); + } + + winSize = (int)mxGetScalar(prhs[5]); + fPnt=(double*)mxGetPr(prhs[4]); + nFeatures=mxGetDimensions(prhs[4]); + + imdims=(int*)malloc(sizeof(int)*cellDims[0]*2); + //iP=(double**)malloc(sizeof(double*)*cellDims[0]); + //iDxP=(double**)malloc(sizeof(double*)*cellDims[0]); + //iDyP=(double**)malloc(sizeof(double*)*cellDims[0]); + //jP=(double**)malloc(sizeof(double*)*cellDims[0]); + + for(int i=0; i6){ + calcPyrLKTrack( iP, iDxP, iDyP, jP, imdims, cellDims[0], fPnt, nFeatures[1], winSize, + newFPnt, valid, accuracy_th, max_iter); + }else{ + calcPyrLKTrack( iP, iDxP, iDyP, jP, imdims, cellDims[0], fPnt, nFeatures[1], winSize, + newFPnt, valid); + } + //idx convert from matlab to c + for(int i=0; i +#include + +#ifndef MAX_LEVEL +# define MAX_LEVEL 5 +#endif +// TODO: add number of corners parameter +void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { + // usage: [newFeaturePnt validFlag ] = + // calcOptFlowPyrLKMex(Ipyr, IdxPyr, IdyPyr, Jpyr, featurePnt, winSize, accuracy_th, max_iter) + // Ipyr, IdxPyr, IdyPyr, Jpyr: levelx1 size cell. + // featurePnt 2xn int + // winSize c_level int + // c_xx c_xy c_yy: image size double* + // image must be double + + + const mxArray* imgArray; + int* imdims; + const int *curImgDims; + const int *nFeatures; + //double **iP, **iDxP, **iDyP, **jP; + double *iP[MAX_LEVEL], *iDxP[MAX_LEVEL], *iDyP[MAX_LEVEL], *jP[MAX_LEVEL]; + double *fPnt, *newFPnt; + char* valid; + double accuracy_th; + int winSize, max_iter; + const int *cellDims = mxGetDimensions(prhs[0]); + + if (nrhs > 6) { + accuracy_th=(double)mxGetScalar(prhs[6]); + max_iter=(int)mxGetScalar(prhs[7]); + } + + winSize = (int)mxGetScalar(prhs[5]); + fPnt=(double*)mxGetPr(prhs[4]); + nFeatures=mxGetDimensions(prhs[4]); + + imdims=(int*)malloc(sizeof(int)*cellDims[0]*2); + //iP=(double**)malloc(sizeof(double*)*cellDims[0]); + //iDxP=(double**)malloc(sizeof(double*)*cellDims[0]); + //iDyP=(double**)malloc(sizeof(double*)*cellDims[0]); + //jP=(double**)malloc(sizeof(double*)*cellDims[0]); + + for(int i=0; i6){ + calcPyrLKTrack( iP, iDxP, iDyP, jP, imdims, cellDims[0], fPnt, nFeatures[1], winSize, + newFPnt, valid, accuracy_th, max_iter); + }else{ + calcPyrLKTrack( iP, iDxP, iDyP, jP, imdims, cellDims[0], fPnt, nFeatures[1], winSize, + newFPnt, valid); + } + //idx convert from matlab to c + for(int i=0; i +#include + +#ifndef MAX_LEVEL +# define MAX_LEVEL 5 +#endif +// TODO: add number of corners parameter +void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { + // usage: [newFeaturePnt validFlag ] = + // calcOptFlowLKPyrWInitMex2(Ipyr, IdxPyr, IdyPyr, Jpyr, featurePnt, winSize, accuracy_th, max_iter, initFPnt) + // Ipyr, IdxPyr, IdyPyr, Jpyr: levelx1 size cell. + // featurePnt 2xn int + // winSize c_level int + // c_xx c_xy c_yy: image size double* + // image must be double + + + const mxArray* imgArray; + int* imdims; + const int *curImgDims; + const int *nFeatures; + double *iP[MAX_LEVEL], *iDxP[MAX_LEVEL], *iDyP[MAX_LEVEL], *jP[MAX_LEVEL]; + double *fPnt, *newFPnt, *initFPnt; + char* valid; + double accuracy_th; + int winSize, max_iter; + const int *cellDims = mxGetDimensions(prhs[0]); + + accuracy_th=(double)mxGetScalar(prhs[6]); + max_iter=(int)mxGetScalar(prhs[7]); + initFPnt=(double*)mxGetPr(prhs[8]); + + winSize = (int)mxGetScalar(prhs[5]); + fPnt=(double*)mxGetPr(prhs[4]); + nFeatures=mxGetDimensions(prhs[4]); + + imdims=(int*)malloc(sizeof(int)*cellDims[0]*2); + + for(int i=0; i +#include + +#ifndef MAX_LEVEL +# define MAX_LEVEL 5 +#endif +// TODO: add number of corners parameter +void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { + // usage: [newFeaturePnt validFlag ] = + // calcOptFlowLKPyrWInitMex2(Ipyr, IdxPyr, IdyPyr, Jpyr, featurePnt, winSize, accuracy_th, max_iter, initFPnt) + // Ipyr, IdxPyr, IdyPyr, Jpyr: levelx1 size cell. + // featurePnt 2xn int + // winSize c_level int + // c_xx c_xy c_yy: image size double* + // image must be double + + + const mxArray* imgArray; + int* imdims; + const int *curImgDims; + const int *nFeatures; + double *iP[MAX_LEVEL], *iDxP[MAX_LEVEL], *iDyP[MAX_LEVEL], *jP[MAX_LEVEL]; + double *fPnt, *newFPnt, *initFPnt; + char* valid; + double accuracy_th; + int winSize, max_iter; + const int *cellDims = mxGetDimensions(prhs[0]); + + accuracy_th=(double)mxGetScalar(prhs[6]); + max_iter=(int)mxGetScalar(prhs[7]); + initFPnt=(double*)mxGetPr(prhs[8]); + + winSize = (int)mxGetScalar(prhs[5]); + fPnt=(double*)mxGetPr(prhs[4]); + nFeatures=mxGetDimensions(prhs[4]); + + imdims=(int*)malloc(sizeof(int)*cellDims[0]*2); + + for(int i=0; i +#include + +#ifndef MAX_LEVEL +# define MAX_LEVEL 5 +#endif +// TODO: add number of corners parameter +void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { + // usage: [newFeaturePnt validFlag ] = + // calcOptFlowLKPyrWInitMex2(Ipyr, Jpyr, featurePnt, winSize, accuracy_th, max_iter, initFPnt) + // Ipyr, IdxPyr, IdyPyr, Jpyr: levelx1 size cell. + // featurePnt 2xn int + // winSize c_level int + // c_xx c_xy c_yy: image size double* + // image must be double + + + const mxArray* imgArray; + int* imdims; + const int *curImgDims; + const int *nFeatures; + double *iP[MAX_LEVEL], *jP[MAX_LEVEL]; + double *fPnt, *newFPnt, *initFPnt; + char* valid; + double accuracy_th; + int winSize, max_iter; + const int *cellDims = mxGetDimensions(prhs[0]); + + accuracy_th=(double)mxGetScalar(prhs[4]); + max_iter=(int)mxGetScalar(prhs[5]); + initFPnt=(double*)mxGetPr(prhs[6]); + + winSize = (int)mxGetScalar(prhs[3]); + fPnt=(double*)mxGetPr(prhs[2]); + nFeatures=mxGetDimensions(prhs[2]); + + imdims=(int*)malloc(sizeof(int)*cellDims[0]*2); + + for(int i=0; i +#include + +#define WIN_SIZE 10 +#define PYR_LEVELS 3 + +void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { + // usage: [ newpoints status pyr1 ] = + // calcOpticalFlowPyrLK(im1,im2,oldpoints,pyr1) + // images must be single-channel, 8-bit + // DO NOT PASS SAME IMAGE IN TWICE! + + char *im1_ptr = (char*)mxGetPr(prhs[0]); + char *im2_ptr = (char*)mxGetPr(prhs[1]); + const int *imdims = mxGetDimensions(prhs[0]); + int flags = 0; + int max_iter; + + if(nrhs>3){ + max_iter=(int)mxGetScalar(prhs[3]); + }else{ + max_iter=20; + } + + /* images */ + IplImage *im1 = + cvCreateImageHeader(cvSize(imdims[0], imdims[1]), IPL_DEPTH_8U, 1); + IplImage *im2 = + cvCreateImageHeader(cvSize(imdims[0], imdims[1]), IPL_DEPTH_8U, 1); + im1->imageData = im1_ptr; + im2->imageData = im2_ptr; + + /* coordinate arrays */ + CvPoint2D32f *oldpoints = (CvPoint2D32f*)mxGetPr(prhs[2]); + const int *pointsdim = mxGetDimensions(prhs[2]); + int npoints = pointsdim[1]; + plhs[0] = mxCreateNumericMatrix(2, npoints, mxSINGLE_CLASS, mxREAL); + CvPoint2D32f *newpoints = (CvPoint2D32f*)mxGetPr(plhs[0]); + + /* status array */ + plhs[1] = mxCreateNumericMatrix(1, npoints, mxUINT8_CLASS, mxREAL); + char *status = (char*)mxGetPr(plhs[1]); + + cvCalcOpticalFlowLK(im1, im2, + cvSize(WIN_SIZE, WIN_SIZE), velx, vely + status, + NULL, + cvTermCriteria(CV_TERMCRIT_ITER|CV_TERMCRIT_EPS,max_iter,0.03), + flags + ); +} diff --git a/SD-VBS/common/toolbox/lagrcv/calcOpticalFlowPyrLK.cc b/SD-VBS/common/toolbox/lagrcv/calcOpticalFlowPyrLK.cc new file mode 100755 index 0000000..d4be5ff --- /dev/null +++ b/SD-VBS/common/toolbox/lagrcv/calcOpticalFlowPyrLK.cc @@ -0,0 +1,77 @@ + +/* compile with + mex calcOpticalFlowPyrLK.cc -I/usr/local/opencv/include -L/usr/local/opencv/lib -lcxcore -lcv +*/ + +#include "mex.h" +#include "opencv/cv.h" +#include "opencv/highgui.h" +#include +#include + +#define WIN_SIZE 8 +#define PYR_LEVELS 3 + +void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { + // usage: [ newpoints status pyr1 ] = + // calcOpticalFlowPyrLK(im1,im2,oldpoints,pyr1) + // images must be single-channel, 8-bit + // DO NOT PASS SAME IMAGE IN TWICE! + + char *im1_ptr = (char*)mxGetPr(prhs[0]); + char *im2_ptr = (char*)mxGetPr(prhs[1]); + const int *imdims = mxGetDimensions(prhs[0]); + IplImage *pyr1 = 0, *pyr2 = 0; + int flags = 0; + bool clearPyr1 = false; + int max_iter; + + max_iter=30; + + /* images */ + IplImage *im1 = + cvCreateImageHeader(cvSize(imdims[0], imdims[1]), IPL_DEPTH_8U, 1); + IplImage *im2 = + cvCreateImageHeader(cvSize(imdims[0], imdims[1]), IPL_DEPTH_8U, 1); + im1->imageData = im1_ptr; + im2->imageData = im2_ptr; + + /* allocate pyramids */ + pyr1 = cvCreateImageHeader(cvSize(imdims[0],imdims[1]), IPL_DEPTH_8U, 1); + pyr2 = cvCreateImageHeader(cvSize(imdims[0],imdims[1]), IPL_DEPTH_8U, 1); + // reuse pyramid if given + if (nrhs > 3) { + pyr1->imageData = (char*)mxGetPr(prhs[3]); + flags |= CV_LKFLOW_PYR_A_READY; + } else { + clearPyr1 = true; + cvCreateData(pyr1); + } + + // pyr2 will be reused, so allocate in return value + plhs[2] = mxCreateNumericMatrix(imdims[0], imdims[1], mxUINT8_CLASS, mxREAL); + pyr2->imageData = (char*)mxGetPr(plhs[2]); + + /* coordinate arrays */ + CvPoint2D32f *oldpoints = (CvPoint2D32f*)mxGetPr(prhs[2]); + const int *pointsdim = mxGetDimensions(prhs[2]); + int npoints = pointsdim[1]; + plhs[0] = mxCreateNumericMatrix(2, npoints, mxSINGLE_CLASS, mxREAL); + CvPoint2D32f *newpoints = (CvPoint2D32f*)mxGetPr(plhs[0]); + + /* status array */ + plhs[1] = mxCreateNumericMatrix(1, npoints, mxUINT8_CLASS, mxREAL); + char *status = (char*)mxGetPr(plhs[1]); + + cvCalcOpticalFlowPyrLK(im1, im2, + pyr1, pyr2, + oldpoints, newpoints, npoints, + cvSize(WIN_SIZE, WIN_SIZE), PYR_LEVELS, + status, + NULL, + cvTermCriteria(CV_TERMCRIT_ITER|CV_TERMCRIT_EPS,max_iter,0.03), + flags + ); + if (clearPyr1) + cvReleaseImage(&pyr1); +} diff --git a/SD-VBS/common/toolbox/lagrcv/calcOpticalFlowPyrLK.mexglx b/SD-VBS/common/toolbox/lagrcv/calcOpticalFlowPyrLK.mexglx new file mode 100755 index 0000000..ad5d0e9 Binary files /dev/null and b/SD-VBS/common/toolbox/lagrcv/calcOpticalFlowPyrLK.mexglx differ diff --git a/SD-VBS/common/toolbox/lagrcv/calcResizedImgMex.cc b/SD-VBS/common/toolbox/lagrcv/calcResizedImgMex.cc new file mode 100755 index 0000000..9c1aed7 --- /dev/null +++ b/SD-VBS/common/toolbox/lagrcv/calcResizedImgMex.cc @@ -0,0 +1,33 @@ + +/* compile with +rm liblagrcv.a +gcc -c lagrcv.cpp +ar rc liblagrcv.a lagrcv.o +ranlib liblagrcv.a +mex7 calcTextureMex.cc -L/home/ikkjin/LagrMatlab/opencv/matlab -llagrcv -I/home/ikkjin/LagrMatlab/opencv/matlab/ +*/ + +#include "mex.h" +#include "lagrcv.h" +#include +#include + +// TODO: add number of corners parameter +void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { + // usage: [dxPye dyPyr] = + // calcGradientPyrMex(imagePyr) + + double *image, *retImg; + int newSizeY, newSizeX; + const int *imdims; + + image=(double*)mxGetPr(prhs[0]); + imdims = mxGetDimensions(prhs[0]); + + newSizeY=(imdims[0]+1)/2; + newSizeX=(imdims[1]+1)/2; + plhs[0] = mxCreateNumericMatrix(newSizeY, newSizeX, mxDOUBLE_CLASS, mxREAL); + retImg=(double*)mxGetPr(plhs[0]); + + calcImgResize(image, imdims[0], imdims[1], retImg, newSizeY, newSizeX); +} diff --git a/SD-VBS/common/toolbox/lagrcv/calcResizedImgMex.mexa64 b/SD-VBS/common/toolbox/lagrcv/calcResizedImgMex.mexa64 new file mode 100755 index 0000000..0f66793 Binary files /dev/null and b/SD-VBS/common/toolbox/lagrcv/calcResizedImgMex.mexa64 differ diff --git a/SD-VBS/common/toolbox/lagrcv/calcResizedImgMex.mexglx b/SD-VBS/common/toolbox/lagrcv/calcResizedImgMex.mexglx new file mode 100755 index 0000000..192ea5a Binary files /dev/null and b/SD-VBS/common/toolbox/lagrcv/calcResizedImgMex.mexglx differ diff --git a/SD-VBS/common/toolbox/lagrcv/calcSobelMex.cc b/SD-VBS/common/toolbox/lagrcv/calcSobelMex.cc new file mode 100755 index 0000000..8667ec4 --- /dev/null +++ b/SD-VBS/common/toolbox/lagrcv/calcSobelMex.cc @@ -0,0 +1,32 @@ + +/* compile with +rm liblagrcv.a +gcc -c lagrcv.cpp +ar rc liblagrcv.a lagrcv.o +ranlib liblagrcv.a +mex7 calcTextureMex.cc -L/home/ikkjin/LagrMatlab/opencv/matlab -llagrcv -I/home/ikkjin/LagrMatlab/opencv/matlab/ +*/ + +#include "mex.h" +#include "lagrcv.h" +#include +#include + +// TODO: add number of corners parameter +void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { + // usage: [dx dy] = + // calcSobelMex(image) + + double *image, *dx, *dy; + const int *imdims; + + image=(double*)mxGetPr(prhs[0]); + imdims = mxGetDimensions(prhs[0]); + + plhs[0] = mxCreateNumericMatrix(imdims[0], imdims[1], mxDOUBLE_CLASS, mxREAL); + plhs[1] = mxCreateNumericMatrix(imdims[0], imdims[1], mxDOUBLE_CLASS, mxREAL); + dx=(double*)mxGetPr(plhs[0]); + dy=(double*)mxGetPr(plhs[1]); + + calcSobel(image, imdims[0], imdims[1], dx, dy); +} diff --git a/SD-VBS/common/toolbox/lagrcv/calcSobelMex.mexa64 b/SD-VBS/common/toolbox/lagrcv/calcSobelMex.mexa64 new file mode 100755 index 0000000..272563f Binary files /dev/null and b/SD-VBS/common/toolbox/lagrcv/calcSobelMex.mexa64 differ diff --git a/SD-VBS/common/toolbox/lagrcv/calcSobelMex.mexglx b/SD-VBS/common/toolbox/lagrcv/calcSobelMex.mexglx new file mode 100755 index 0000000..9fc5d10 Binary files /dev/null and b/SD-VBS/common/toolbox/lagrcv/calcSobelMex.mexglx differ diff --git a/SD-VBS/common/toolbox/lagrcv/calcSobelPyrMex.cc b/SD-VBS/common/toolbox/lagrcv/calcSobelPyrMex.cc new file mode 100755 index 0000000..314c835 --- /dev/null +++ b/SD-VBS/common/toolbox/lagrcv/calcSobelPyrMex.cc @@ -0,0 +1,44 @@ + +/* compile with +rm liblagrcv.a +gcc -c lagrcv.cpp +ar rc liblagrcv.a lagrcv.o +ranlib liblagrcv.a +mex7 calcTextureMex.cc -L/home/ikkjin/LagrMatlab/opencv/matlab -llagrcv -I/home/ikkjin/LagrMatlab/opencv/matlab/ +*/ + +#include "mex.h" +#include "lagrcv.h" +#include +#include + +// TODO: add number of corners parameter +void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { + // usage: [dxPye dyPyr] = + // calcGradientPyrMex(imagePyr) + + const int *cellDims = mxGetDimensions(prhs[0]); + double *image; + const mxArray* imgArray; + mxArray *dxArray, *dyArray; + double *dx, *dy; + const int *imdims; + + plhs[0] = mxCreateCellArray(2, cellDims); + plhs[1] = mxCreateCellArray(2, cellDims); + + for(int i=0; i +#include + +// TODO: add number of corners parameter +void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { + // usage: [dxPye dyPyr] = + // calcGradientPyrMex(imagePyr) + + double *image, *retImg; + int newSizeY, newSizeX; + const int *imdims; + + image=(double*)mxGetPr(prhs[0]); + imdims = mxGetDimensions(prhs[0]); + + newSizeY=imdims[0]/2; + newSizeX=imdims[1]/2; + plhs[0] = mxCreateNumericMatrix(newSizeY, newSizeX, mxDOUBLE_CLASS, mxREAL); + retImg=(double*)mxGetPr(plhs[0]); + + calcSubSampleAvg(image, imdims[0], imdims[1], retImg, newSizeY, newSizeX); +} diff --git a/SD-VBS/common/toolbox/lagrcv/calcSubsampleAvgMex.mexa64 b/SD-VBS/common/toolbox/lagrcv/calcSubsampleAvgMex.mexa64 new file mode 100755 index 0000000..6cf4f0e Binary files /dev/null and b/SD-VBS/common/toolbox/lagrcv/calcSubsampleAvgMex.mexa64 differ diff --git a/SD-VBS/common/toolbox/lagrcv/calcSubsampleAvgMex.mexglx b/SD-VBS/common/toolbox/lagrcv/calcSubsampleAvgMex.mexglx new file mode 100755 index 0000000..f8acfde Binary files /dev/null and b/SD-VBS/common/toolbox/lagrcv/calcSubsampleAvgMex.mexglx differ diff --git a/SD-VBS/common/toolbox/lagrcv/calcTextureMex.cc b/SD-VBS/common/toolbox/lagrcv/calcTextureMex.cc new file mode 100755 index 0000000..f91d184 --- /dev/null +++ b/SD-VBS/common/toolbox/lagrcv/calcTextureMex.cc @@ -0,0 +1,53 @@ + +/* compile with +rm liblagrcv.a +gcc -c lagrcv.cpp +ar rc liblagrcv.a lagrcv.o +ranlib liblagrcv.a +mex7 calcTextureMex.cc -L/home/ikkjin/LagrMatlab/opencv/matlab -llagrcv -I/home/ikkjin/LagrMatlab/opencv/matlab/ +*/ + +#include "mex.h" +#include "lagrcv.h" +#include +#include + +// TODO: add number of corners parameter +void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { + // usage: [ lambda tr det c_xx c_xy c_yy] = + // goodFeaturesToTrack(image, winSize) + // image must be single-channel, 8-bit + + double *image; + int winSize = (int)mxGetScalar(prhs[1]); + double *lambda, *tr, *det, *c_xx, *c_xy, *c_yy; + const int *imdims; + //double dx[360000];//[MAX_IMAGE_SIZE_1D]; + //double dy[360000];//[MAX_IMAGE_SIZE_1D]; + double *dx, *dy; + + image = (double*)mxGetPr(prhs[0]); + imdims = mxGetDimensions(prhs[0]); + dx=(double*)malloc(sizeof(double)*imdims[0]*imdims[1]); + dy=(double*)malloc(sizeof(double)*imdims[0]*imdims[1]); + + plhs[0] = mxCreateNumericMatrix(imdims[0], imdims[1], mxDOUBLE_CLASS, mxREAL); + plhs[1] = mxCreateNumericMatrix(imdims[0], imdims[1], mxDOUBLE_CLASS, mxREAL); + plhs[2] = mxCreateNumericMatrix(imdims[0], imdims[1], mxDOUBLE_CLASS, mxREAL); + plhs[3] = mxCreateNumericMatrix(imdims[0], imdims[1], mxDOUBLE_CLASS, mxREAL); + plhs[4] = mxCreateNumericMatrix(imdims[0], imdims[1], mxDOUBLE_CLASS, mxREAL); + plhs[5] = mxCreateNumericMatrix(imdims[0], imdims[1], mxDOUBLE_CLASS, mxREAL); + + lambda = (double*)mxGetPr(plhs[0]); + tr = (double*)mxGetPr(plhs[1]); + det = (double*)mxGetPr(plhs[2]); + c_xx = (double*)mxGetPr(plhs[3]); + c_xy = (double*)mxGetPr(plhs[4]); + c_yy = (double*)mxGetPr(plhs[5]); + + calcSobel(image, imdims[0], imdims[1], dx, dy); + calcGoodFeature(dx, dy, imdims[0], imdims[1], winSize, + lambda, tr, det, c_xx, c_xy, c_yy); + free(dx); + free(dy); +} diff --git a/SD-VBS/common/toolbox/lagrcv/calcTextureMex.mexa64 b/SD-VBS/common/toolbox/lagrcv/calcTextureMex.mexa64 new file mode 100755 index 0000000..3c023ea Binary files /dev/null and b/SD-VBS/common/toolbox/lagrcv/calcTextureMex.mexa64 differ diff --git a/SD-VBS/common/toolbox/lagrcv/calcTextureMex.mexglx b/SD-VBS/common/toolbox/lagrcv/calcTextureMex.mexglx new file mode 100755 index 0000000..f8e0c99 Binary files /dev/null and b/SD-VBS/common/toolbox/lagrcv/calcTextureMex.mexglx differ diff --git a/SD-VBS/common/toolbox/lagrcv/calcTexturePyrMex.cc b/SD-VBS/common/toolbox/lagrcv/calcTexturePyrMex.cc new file mode 100755 index 0000000..3c332ca --- /dev/null +++ b/SD-VBS/common/toolbox/lagrcv/calcTexturePyrMex.cc @@ -0,0 +1,54 @@ + +/* compile with +rm liblagrcv.a +gcc -c lagrcv.cpp +ar rc liblagrcv.a lagrcv.o +ranlib liblagrcv.a +mex7 calcTextureMex.cc -L/home/ikkjin/LagrMatlab/opencv/matlab -llagrcv -I/home/ikkjin/LagrMatlab/opencv/matlab/ +*/ + +#include "mex.h" +#include "lagrcv.h" +#include +#include + +// TODO: add number of corners parameter +void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { + // usage: [ lambda tr det c_xx c_xy c_yy] = + // calcTexturePyrMex(dxPyr, dyPyr, winSize, level) + // image is assumed to be double + // the lowest level is 1 + + const int *cellDims = mxGetDimensions(prhs[0]); + int level=0; + char winSize = (char )mxGetScalar(prhs[2]); + double *dx, *dy; + const mxArray* dxArray, * dyArray; + const int *imdims; + double *tr, *det, *lambda, *c_xx, *c_xy, *c_yy; + + if (nrhs > 3) level = (int)mxGetScalar(prhs[3])-1; + + dxArray= mxGetCell(prhs[0],level); + dyArray= mxGetCell(prhs[1],level); + dx=mxGetPr(dxArray); + dy=mxGetPr(dyArray); + imdims = mxGetDimensions(dxArray); + + plhs[0] = mxCreateNumericMatrix(imdims[0], imdims[1], mxDOUBLE_CLASS, mxREAL); + plhs[1] = mxCreateNumericMatrix(imdims[0], imdims[1], mxDOUBLE_CLASS, mxREAL); + plhs[2] = mxCreateNumericMatrix(imdims[0], imdims[1], mxDOUBLE_CLASS, mxREAL); + plhs[3] = mxCreateNumericMatrix(imdims[0], imdims[1], mxDOUBLE_CLASS, mxREAL); + plhs[4] = mxCreateNumericMatrix(imdims[0], imdims[1], mxDOUBLE_CLASS, mxREAL); + plhs[5] = mxCreateNumericMatrix(imdims[0], imdims[1], mxDOUBLE_CLASS, mxREAL); + + lambda = (double*)mxGetPr(plhs[0]); + tr = (double*)mxGetPr(plhs[1]); + det = (double*)mxGetPr(plhs[2]); + c_xx = (double*)mxGetPr(plhs[3]); + c_xy = (double*)mxGetPr(plhs[4]); + c_yy = (double*)mxGetPr(plhs[5]); + + calcGoodFeature(dx, dy, imdims[0], imdims[1], winSize, lambda, tr, det, c_xx, c_xy, c_yy); + +} diff --git a/SD-VBS/common/toolbox/lagrcv/calcTexturePyrMex.mexa64 b/SD-VBS/common/toolbox/lagrcv/calcTexturePyrMex.mexa64 new file mode 100755 index 0000000..ebede53 Binary files /dev/null and b/SD-VBS/common/toolbox/lagrcv/calcTexturePyrMex.mexa64 differ diff --git a/SD-VBS/common/toolbox/lagrcv/calcTexturePyrMex.mexglx b/SD-VBS/common/toolbox/lagrcv/calcTexturePyrMex.mexglx new file mode 100755 index 0000000..697ceec Binary files /dev/null and b/SD-VBS/common/toolbox/lagrcv/calcTexturePyrMex.mexglx differ diff --git a/SD-VBS/common/toolbox/lagrcv/dummyMex.cc b/SD-VBS/common/toolbox/lagrcv/dummyMex.cc new file mode 100755 index 0000000..0799182 --- /dev/null +++ b/SD-VBS/common/toolbox/lagrcv/dummyMex.cc @@ -0,0 +1,58 @@ + +/* compile with +rm liblagrcv.a +gcc -c lagrcv.cpp +ar rc liblagrcv.a lagrcv.o +ranlib liblagrcv.a +mex7 calcTextureMex.cc -L/home/ikkjin/LagrMatlab/opencv/matlab -llagrcv -I/home/ikkjin/LagrMatlab/opencv/matlab/ +*/ + +#include "mex.h" +#include "lagrcv.h" +#include +#include + +// TODO: add number of corners parameter +void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { + // usage: [newFeaturePnt validFlag ] = + // calcOptFlowPyrLKMex(Ipyr, IdxPyr, IdyPyr, Jpyr, featurePnt, winSize, c_level, c_det, c_xx, c_xy, c_yy) + // Ipyr, IdxPyr, IdyPyr, Jpyr: levelx1 size cell. + // featurePnt 2xn int + // winSize c_level int + // c_xx c_xy c_yy: image size double* + // image must be single-channel, 8-bit + + + double* fPntDouble; + const int *nFeatures; + char* valid; + int *fPnt, *newFPnt; + + fPntDouble=(double*)mxGetPr(prhs[0]); + nFeatures=mxGetDimensions(prhs[0]); + fPnt=(int*)malloc(sizeof(int)*nFeatures[0]*nFeatures[1]); + + printf("nFeatures %d, %d", nFeatures[0], nFeatures[1]); + //plhs[0] = mxCreateNumericMatrix(nFeatures[0], nFeatures[1], mxINT32_CLASS, mxREAL); + plhs[0] = mxCreateNumericArray(2,nFeatures,mxINT32_CLASS, mxREAL); + //plhs[1] = mxCreateNumericMatrix(1, nFeatures[1], mxINT32_CLASS, mxREAL); + plhs[1] = mxCreateNumericArray(1,nFeatures+1,mxUINT8_CLASS, mxREAL); + + newFPnt = (int*)mxGetPr(plhs[0]); + valid = (char*)mxGetPr(plhs[1]); + + //idx convert from matlab to c + for(int i=0; i +#include + +//#define MAX_CORNERS 500 +#define WIN_SIZE 5 + +void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { + // usage: [ features ] = + // findCornerSubPix(image, features) + // image must be single-channel, 8-bit + + char *image_pr = (char*)mxGetPr(prhs[0]); + const int *imdims = mxGetDimensions(prhs[0]); + IplImage *image = + cvCreateImageHeader(cvSize(imdims[0], imdims[1]), IPL_DEPTH_8U, 1); + image->imageData = image_pr; + + const int *feature_dims = mxGetDimensions(prhs[1]); + int nfeatures = feature_dims[1]; + plhs[0] = mxCreateNumericMatrix(2, nfeatures, mxSINGLE_CLASS, mxREAL); + CvPoint2D32f *newfeatures = (CvPoint2D32f*)mxGetPr(plhs[0]); + CvPoint2D32f *oldfeatures = (CvPoint2D32f*)mxGetPr(prhs[1]); + // plhs[0] = mxDuplicateArray(prhs[1]); + // CvPoint2D32f *newfeatures = (CvPoint2D32f*)mxGetPr(plhs[0]); + memcpy(newfeatures, oldfeatures, sizeof(float)*2*nfeatures); + + cvFindCornerSubPix(image, newfeatures, nfeatures, + cvSize(WIN_SIZE,WIN_SIZE), + cvSize(-1,-1), + cvTermCriteria(CV_TERMCRIT_ITER|CV_TERMCRIT_EPS,20,0.03)); +} diff --git a/SD-VBS/common/toolbox/lagrcv/goodFeaturesToTrack.cc b/SD-VBS/common/toolbox/lagrcv/goodFeaturesToTrack.cc new file mode 100755 index 0000000..376a096 --- /dev/null +++ b/SD-VBS/common/toolbox/lagrcv/goodFeaturesToTrack.cc @@ -0,0 +1,62 @@ + +/* compile with + mex goodFeaturesToTrack.cc -I/usr/local/opencv/include -L/usr/local/opencv/lib -lcxcore -lcv +*/ + +#include "mex.h" +#include "opencv/cv.h" +#include "opencv/highgui.h" +#include +#include + +#define MAX_CORNERS 500 + +IplImage *eigtemp = NULL, *temp2 = NULL; + +// TODO: add number of corners parameter +void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { + // usage: [ features numvalid ] = + // goodFeaturesToTrack(image, quality, mindist, mask) + // image must be single-channel, 8-bit + // quality = minimum acceptable ratio of eigenvalues + // mindist = minimum distance between corners + // mask (optional) = bitmap mask "region of interest" (MUST BE uint8 TYPE!) + + char *image_pr = (char*)mxGetPr(prhs[0]); + // int imdims[] = { (int)d_imdims[0], (int)d_imdims[1] }; + const int *imdims = mxGetDimensions(prhs[0]); + double quality = mxGetScalar(prhs[1]); + double mindist = mxGetScalar(prhs[2]); + bool use_roi = nrhs > 3; + + plhs[0] = mxCreateNumericMatrix(2, MAX_CORNERS, mxSINGLE_CLASS, mxREAL); + plhs[1] = mxCreateNumericMatrix(1, 1, mxINT32_CLASS, mxREAL); + + CvPoint2D32f *corner_coords = (CvPoint2D32f*)mxGetPr(plhs[0]); + int *corner_count = (int*)mxGetPr(plhs[1]); + *corner_count = MAX_CORNERS; + + if (eigtemp == NULL) { + eigtemp = cvCreateImage(cvSize(imdims[0],imdims[1]), IPL_DEPTH_32F, 1); + temp2 = cvCreateImage(cvSize(imdims[0],imdims[1]), IPL_DEPTH_32F, 1); + } + + IplImage *image = + cvCreateImageHeader(cvSize(imdims[0], imdims[1]), IPL_DEPTH_8U, 1); + image->imageData = image_pr; + + IplImage *roimask = NULL; + if (use_roi) { + roimask = cvCreateImage(cvSize(imdims[0],imdims[1]), IPL_DEPTH_8U, 1); + roimask->imageData = (char*)mxGetPr(prhs[3]); + } + + cvGoodFeaturesToTrack(image, + eigtemp, temp2, + corner_coords, + corner_count, + quality, + mindist, + roimask + ); +} diff --git a/SD-VBS/common/toolbox/lagrcv/goodFeaturesToTrack.mexglx b/SD-VBS/common/toolbox/lagrcv/goodFeaturesToTrack.mexglx new file mode 100755 index 0000000..0fe9080 Binary files /dev/null and b/SD-VBS/common/toolbox/lagrcv/goodFeaturesToTrack.mexglx differ diff --git a/SD-VBS/common/toolbox/lagrcv/lagrcv.cpp b/SD-VBS/common/toolbox/lagrcv/lagrcv.cpp new file mode 100755 index 0000000..4f24b5d --- /dev/null +++ b/SD-VBS/common/toolbox/lagrcv/lagrcv.cpp @@ -0,0 +1,840 @@ +#include "lagrcv.h" +/* +void calcImagePyr(char *src, int sizeY, int sizeX, int level, char *pyr){ + pyr=(char*) malloc(sizeof(char)*(int)sizeY*sizeX*4/3); + int i, startPnt, nX, nY; + + memcpy(pyr,src, sizeY*sizeX); + nY=sizeY; + nX=sizeX; + for(i=0; i> 1; + nX = (nX + 1) >> 1; + calcSubsample(pyr, sizeY, sizeX, pyr+sizeY*sizeX) + } + free(pyr); +} +*/ + +void calcSubSampleAvg(double *src, int sizeY, int sizeX, double *dest, int destSizeY, int destSizeX){ + int i, j, idx, + destI, destJ, idxDest; + for(i=0, destI=0; destI0)?sum[idx-1]:0) + + ((i>0)?sum[idx-sizeY]:0) + - ((i>0&&j>0)?sum[idx-sizeY-1]:0); + } + } +*/ + idxDelta[0]=halfSize*sizeY+halfSize; + idxDelta[1]=-halfSize*sizeY+halfSize; + idxDelta[2]=halfSize*sizeY-halfSize; + idxDelta[3]=-halfSize*sizeY-halfSize; + for(i=halfSize; i=0; level--){ + x+=x; y+=y; dX+=dX; dY+=dY; + imgSize[0]=imgDims[level*2+0]; //y,x + imgSize[1]=imgDims[level*2+1]; //y,x + + c_xx=c_xy=c_yy=0; + //when feature goes out to the boundary. + if((x-winSize-1)<0 || (y-winSize-1)<0 + || (y+winSize+1+1)>=imgSize[0] || (x+winSize+1+1)>=imgSize[1]){ + //winSize+1due to interpolation + //error or skip the level?? + valid[i]=0; + break; + } + + getInterpolatePatch(iP[level], imgSize, x, y, winSize+1, iPatch); //to calculate iDx, iDy + calcSobel(iPatch, (winSize+1)*2, (winSize+1)*2, iDxPatch, iDyPatch); + for(k=0; k <(winSize*2); k++ ){ + memcpy( iPatch + k*winSize*2, iPatch + (k+1)*(winSize+1)*2 + 1, winSize*2 ); + memcpy( iDxPatch + k*winSize*2, iDxPatch + (k+1)*(winSize+1)*2 + 1, winSize*2 ); + memcpy( iDyPatch + k*winSize*2, iDyPatch + (k+1)*(winSize+1)*2 + 1, winSize*2 ); + } + + for(idx=0; idx=imgSize[0] || (x+dX+winSize+1)>=imgSize[1]){ + //winSize+1due to interpolation + //error or skip the level?? + valid[i]=0; + break; + } + getInterpolatePatch(jP[level], imgSize, x+dX, y+dY, winSize, jPatch); + eX=eY=0; + for(idx=0;idx0 && (mX + prevMX) < 0.01 && (mX+prevMX) > -0.01 + && (mY + prevMY) < 0.01 && (mY+prevMY) > -0.01) + { + dX -= mX*0.5f; + dY -= mY*0.5f; + break; + } + prevMX=mX; + prevMY=mY; + } + if(k==max_iter){ + valid[i]=0; + } + } + newFPnt[i*2+0]=fPnt[i*2+0]+dX; + newFPnt[i*2+1]=fPnt[i*2+1]+dY; +/* + if(valid[i] + || (x+dX-winSize)<0 || (y+dY-winSize)<0 + || (y+dY+winSize+1)>=imgSize[0] || (x+dX+winSize+1)>=imgSize[1]){ + newFPnt[i*2+0]=fPnt[i*2+0]+dX; + newFPnt[i*2+1]=fPnt[i*2+1]+dY; + getInterpolatePatch(jP[0], imgSize, newFPnt[i*2+0], newFPnt[i*2+0], winSize, jPatch); + dIt=0; + for(idx=0;idxwinSizeSq*50000){ + valid[i]=0; + } + }else{ + newFPnt[i*2+0]=0; + newFPnt[i*2+1]=0; + } +*/ + } + free(iPatch); + free(jPatch); + free(iDxPatch); + free(iDyPatch); +} +void calcPyrLKTrackWInit(double** iP, double** iDxP, double** iDyP, double** jP, const int* imgDims, int pLevel, + double* fPnt, int nFeatures, int winSize, + double* newFPnt, double* initFPnt, + char* valid, double accuracy_th, int max_iter){ + + double x, y, eX, eY, dX, dY, mX, mY, prevMX, prevMY, c_xx, c_xy, c_yy, c_det, dIt; + double* iPatch, *jPatch, *iDxPatch, *iDyPatch; + int level, winSizeSq; + int i, k, idx; + int imgSize[2]; + + static const double rate[]={1, 0.5, 0.25, 0.125, 0.0625, 0.03125}; + winSizeSq=4*winSize*winSize; + + iPatch=(double*) malloc(sizeof(double)*winSizeSq); + jPatch=(double*) malloc(sizeof(double)*winSizeSq); + iDxPatch=(double*) malloc(sizeof(double)*winSizeSq); + iDyPatch=(double*) malloc(sizeof(double)*winSizeSq); + + for(i=0; i=0; level--){ + x+=x; y+=y; dX+=dX; dY+=dY; + imgSize[0]=imgDims[level*2+0]; //y,x + imgSize[1]=imgDims[level*2+1]; //y,x + + c_xx=c_xy=c_yy=0; + //when feature goes out to the boundary. + if((x-winSize)<0 || (y-winSize)<0 + || (y+winSize+1)>=imgSize[0] || (x+winSize+1)>=imgSize[1]){ + //winSize+1due to interpolation + //error or skip the level?? + valid[i]=0; + break; + } + + getInterpolatePatch(iP[level], imgSize, x, y, winSize, iPatch); + getInterpolatePatch(iDxP[level], imgSize, x, y, winSize, iDxPatch); + getInterpolatePatch(iDyP[level], imgSize, x, y, winSize, iDyPatch); + + for(idx=0; idx=imgSize[0] || (x+dX+winSize+1)>=imgSize[1]){ + //winSize+1due to interpolation + //error or skip the level?? + valid[i]=0; + break; + } + getInterpolatePatch(jP[level], imgSize, x+dX, y+dY, winSize, jPatch); + eX=eY=0; + for(idx=0;idx0 && (mX + prevMX) < 0.01 && (mX+prevMX) > -0.01 + && (mY + prevMY) < 0.01 && (mY+prevMY) > -0.01) + { + dX -= mX*0.5f; + dY -= mY*0.5f; + break; + } + prevMX=mX; + prevMY=mY; + } + if(k==max_iter){ + valid[i]=0; + } + } + newFPnt[i*2+0]=fPnt[i*2+0]+dX; + newFPnt[i*2+1]=fPnt[i*2+1]+dY; +/* + if(valid[i] + || (x+dX-winSize)<0 || (y+dY-winSize)<0 + || (y+dY+winSize+1)>=imgSize[0] || (x+dX+winSize+1)>=imgSize[1]){ + newFPnt[i*2+0]=fPnt[i*2+0]+dX; + newFPnt[i*2+1]=fPnt[i*2+1]+dY; + getInterpolatePatch(jP[0], imgSize, newFPnt[i*2+0], newFPnt[i*2+0], winSize, jPatch); + dIt=0; + for(idx=0;idxwinSizeSq*50000){ + valid[i]=0; + } + }else{ + newFPnt[i*2+0]=0; + newFPnt[i*2+1]=0; + } +*/ + } + free(iPatch); + free(jPatch); + free(iDxPatch); + free(iDyPatch); +} +void calcPyrLKTrack(double** iP, double** iDxP, double** iDyP, double** jP, const int* imgDims, int pLevel, + double* fPnt, int nFeatures, int winSize, + double* newFPnt, char* valid, double accuracy_th, int max_iter){ + + double x, y, eX, eY, dX, dY, mX, mY, c_xx, c_xy, c_yy, c_det, dIt; + double* iPatch, *jPatch, *iDxPatch, *iDyPatch; + int level, winSizeSq; + int i, k, idx; + int imgSize[2]; + + static const double rate[]={1, 0.5, 0.25, 0.125, 0.0625, 0.03125}; + winSizeSq=4*winSize*winSize; + + iPatch=(double*) malloc(sizeof(double)*winSizeSq); + jPatch=(double*) malloc(sizeof(double)*winSizeSq); + iDxPatch=(double*) malloc(sizeof(double)*winSizeSq); + iDyPatch=(double*) malloc(sizeof(double)*winSizeSq); + + for(i=0; i=0; level--){ + x+=x; y+=y; dX+=dX; dY+=dY; + imgSize[0]=imgDims[level*2+0]; //y,x + imgSize[1]=imgDims[level*2+1]; //y,x + + c_xx=c_xy=c_yy=0; + //when feature goes out to the boundary. + if((x-winSize)<0 || (y-winSize)<0 + || (y+winSize+1)>=imgSize[0] || (x+winSize+1)>=imgSize[1]){ + //winSize+1due to interpolation + //error or skip the level?? + valid[i]=0; + break; + } + + getInterpolatePatch(iP[level], imgSize, x, y, winSize, iPatch); + getInterpolatePatch(iDxP[level], imgSize, x, y, winSize, iDxPatch); + getInterpolatePatch(iDyP[level], imgSize, x, y, winSize, iDyPatch); + + for(idx=0; idx=imgSize[0] || (x+dX+winSize+1)>=imgSize[1]){ + //winSize+1due to interpolation + //error or skip the level?? + valid[i]=0; + break; + } + getInterpolatePatch(jP[level], imgSize, x+dX, y+dY, winSize, jPatch); + eX=eY=0; + for(idx=0;idx=imgSize[0] || (x+dX+winSize+1)>=imgSize[1]){ + newFPnt[i*2+0]=fPnt[i*2+0]+dX; + newFPnt[i*2+1]=fPnt[i*2+1]+dY; + getInterpolatePatch(jP[0], imgSize, newFPnt[i*2+0], newFPnt[i*2+0], winSize, jPatch); + dIt=0; + for(idx=0;idxwinSizeSq*50000){ + valid[i]=0; + } + }else{ + newFPnt[i*2+0]=0; + newFPnt[i*2+1]=0; + } +*/ + } + free(iPatch); + free(jPatch); + free(iDxPatch); + free(iDyPatch); +} +void getPatch(double* srcImg, const int* srcDims, double centerX, double centerY, int winSize, double** dstImg){ + int srcIdxX, srcIdxY, dstIdxX; + srcIdxY=(int)centerY-winSize; + for(int i=-winSize; i=imdims[0] || (x+winSize)>=imdims[1]){ + //error or skip the level?? + valid[i]=0; + continue; + } + + getPatch(imgI, imdims, x, y, winSize, iPatch); + getPatch(iDx, imdims, x, y, winSize, iDxPatch); + getPatch(iDy, imdims, x, y, winSize, iDyPatch); + + idx=(int)x*imdims[0]+(int)y; + c_det=c_xx[i]*c_yy[i]-c_xy[i]*c_xy[i]; + if(c_det/(c_xx[i]+c_yy[i]+0.00000001)=imdims[0] || (x+dX+winSize+1)>=imdims[1]){ + //winSize+1due to interpolation + //error or skip the level?? + valid[i]=0; + break; + } + getInterpolatePatch(imgJ, imgSize, x+dX, y+dY, winSize, jPatch); + eX=eY=0; + for(idxCol=0;idxCol<2*winSize;idxCol++){ + for(idxRow=0;idxRow<2*winSize;idxRow++){ + dIt=iPatch[idxCol][idxRow]-jPatch[idxCol*winSize*2+idxRow]; + eX+=dIt*iDxPatch[idxCol][idxRow]; + eY+=dIt*iDyPatch[idxCol][idxRow]; + } + } + mX=c_det*(eX*c_yy[i]-eY*c_xy[i]); + mY=c_det*(-eX*c_xy[i]+eY*c_xx[i]); + dX+=mX; + dY+=mY; + if((mX*mX+mY*mY) +#include +#include +#include +#include +#include +#include + +#define GOOD_FEATURE_LAMBDA_TH 10 +#define LK_ACCURACY_TH 0.03 +#define LK_MAX_ITER 20 +#define LK_MAX_WIN 25 +#define MAX_LEVEL 10 +#define MAX_IMAGE_SIZE_1D 1000000 + +void calcSubSampleAvg(double *src, int sizeY, int sizeX, double *dest, int destSizeY, int destSizeX); +void calcImgBlur(double *src, int sizeY, int sizeX, double *dest); +void calcImgResize(double *src, int sizeY, int sizeX, double *dest, int dstSizeY, int dstSizeX); +void calcGradient(double *src, int sizeY, int sizeX, double *dX, double *dY); +void calcGradient(char *src, int sizeY, int sizeX, char *dX, char *dY); +void calcSobel(double *src, int sizeX, int sizeY, double *dx, double *dy); +void calcGoodFeature(double *dX, double *dY, int sizeY, int sizeX, int winSize, double* lambda, double* tr, double* det, + double* c_xx, double* c_xy, double* c_yy); +void calcGoodFeature(char *dX, char *dY, int sizeY, int sizeX, int winSize, float* lambda, float* tr, float* det); +void calcMinEigenValue(char *dX, char *dY, int sizeY, int sizeX, float* lambda); +void calcAreaSum(int *src, int sizeY, int sizeX, int sizeSum, int *ret); +void calcAreaSum(double *src, int sizeY, int sizeX, int sizeSum, double *ret); +void calcPyrLKTrack(double** iP, double** iDxP, double** iDyP, double** jP, const int* imgDims, int pLevel, + double* fPnt, int nFeatures, int winSize, + double* newFPnt, char* valid); +void calcPyrLKTrack(double** iP, double** iDxP, double** iDyP, double** jP, const int* imgDims, int pLevel, + double* fPnt, int nFeatures, int winSize, + double* newFPnt, char* valid, + double accuracy_th, int iter); +void calcLKTrack(double* imgI, double* iDx, double* iDy, double* imgJ, const int* imdims, + double* c_xx, double* c_xy, double* c_yy, + double* fPnt, double* initPnt, int nFeatures, int winSize, + double* newFPnt, char* valid, + double accuracy_th, int max_iter); +void calcLKTrack(double* imgI, double* iDx, double* iDy, double* imgJ, const int* imdims, + double* c_xx, double* c_xy, double* c_yy, + double* fPnt, double* initPnt, int nFeatures, int winSize, + double* newFPnt, char* valid); +void calcPyrLKTrackWInit(double** iP, double** iDxP, double** iDyP, double** jP, const int* imgDims, int pLevel, + double* fPnt, int nFeatures, int winSize, + double* newFPnt, double* initFPnt, + char* valid, double accuracy_th, int max_iter); +void calcPyrLKTrackWInit(double** iP, double** jP, const int* imgDims, int pLevel, + double* fPnt, int nFeatures, int winSize, + double* newFPnt, double* initFPnt, + char* valid, double accuracy_th, int max_iter); diff --git a/SD-VBS/common/toolbox/lagrcv/liblagrcv.a b/SD-VBS/common/toolbox/lagrcv/liblagrcv.a new file mode 100755 index 0000000..a7a39ae Binary files /dev/null and b/SD-VBS/common/toolbox/lagrcv/liblagrcv.a differ diff --git a/SD-VBS/common/toolbox/lagrcv/lk_flow.cc b/SD-VBS/common/toolbox/lagrcv/lk_flow.cc new file mode 100755 index 0000000..c083048 --- /dev/null +++ b/SD-VBS/common/toolbox/lagrcv/lk_flow.cc @@ -0,0 +1,76 @@ + +/* compile with + lk_flow.cc -I/usr/local/opencv/include -L/usr/local/opencv/lib -lcxcore -lcv +*/ + +#include "mex.h" +#include "opencv/cv.h" +#include "opencv/highgui.h" +#include +#include + +void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { + // usage: [ velx vely ] = lk_flow(image1,image2,winsize) + // images must be single-channel, 8-bit + + const int *backwards_imdims = mxGetDimensions(prhs[0]); + int imdims[2] = { backwards_imdims[1], backwards_imdims[0] }; + int winsize = (int)mxGetScalar(prhs[2]); + plhs[0] = mxCreateNumericArray(2, imdims, mxSINGLE_CLASS, mxREAL); + plhs[1] = mxCreateNumericArray(2, imdims, mxSINGLE_CLASS, mxREAL); + + printf("imsize %d %d\n", imdims[0], imdims[1]); + + IplImage *im1 = + cvCreateImageHeader(cvSize(imdims[0], imdims[1]), IPL_DEPTH_8U, 1); + IplImage *im2 = + cvCreateImageHeader(cvSize(imdims[0], imdims[1]), IPL_DEPTH_8U, 1); + IplImage *flow_x = + cvCreateImageHeader(cvSize(imdims[0], imdims[1]), IPL_DEPTH_32F, 1); + IplImage *flow_y = + cvCreateImageHeader(cvSize(imdims[0], imdims[1]), IPL_DEPTH_32F, 1); + + im1->imageData = (char*)mxGetPr(prhs[0]); + im2->imageData = (char*)mxGetPr(prhs[1]); + flow_x->imageData = (char*)mxGetPr(plhs[0]); + flow_y->imageData = (char*)mxGetPr(plhs[1]); + + cvCalcOpticalFlowLK(im1, im2, cvSize(winsize,winsize), flow_x, flow_y); + + for (int row = 0; row < imdims[0]; row += 10) { + for (int col = 0; col < imdims[1]; col += 10) { + cvLine(im1, cvPoint(col,row), + cvPoint(int(col + flow_x->imageData[imdims[1] * row + col]), + int(row + flow_y->imageData[imdims[1] * row + col])), + CV_RGB(1,0,0), + 1, + CV_AA, + 0); + + } + } + + cvDestroyAllWindows(); + cvNamedWindow("imfoo",CV_WINDOW_AUTOSIZE); + // IplImage *myim = cvLoadImage("lena.jpg", -1); + cvShowImage("imfoo",im1); + // cvShowImage("imfoo",myim); + cvWaitKey(0); + + // cvCircle(flow_x, cvPoint( 40, 20), 15, CV_RGB(10,100,100), 5); + + /* + FILE* filefx = fopen("fx.pgm", "w"); + FILE* filefy = fopen("fy.pgm", "w"); + fprintf(filefx, "P5\n%d %d\n255\n", imdims[1], imdims[0]); + fprintf(filefy, "P5\n%d %d\n255\n", imdims[1], imdims[0]); + float *ptr = (float*)flow_x->imageData; + for (int i = 0; i < imdims[1] * imdims[0]; i++) { + // if (fabs(++ptr*) > 0.1) + if (fabs(*ptr++) > 0.1) fprintf(filefx, "1"); + else fprintf(filefx, "0"); + } + fclose(filefx); + fclose(filefy); + */ +} diff --git a/SD-VBS/common/toolbox/lagrcv/lk_flow.mexglx b/SD-VBS/common/toolbox/lagrcv/lk_flow.mexglx new file mode 100755 index 0000000..d6c1136 Binary files /dev/null and b/SD-VBS/common/toolbox/lagrcv/lk_flow.mexglx differ diff --git a/SD-VBS/common/toolbox/lagrcv/test.cc b/SD-VBS/common/toolbox/lagrcv/test.cc new file mode 100755 index 0000000..d18144c --- /dev/null +++ b/SD-VBS/common/toolbox/lagrcv/test.cc @@ -0,0 +1,34 @@ + +/* compile with + mex goodFeaturesToTrack.cc -I/usr/local/opencv/include -L/usr/local/opencv/lib -lcxcore -lcv +mex test.cc -L/home/ikkjin/LagrMatlab/opencv/matlab -llagrcv -I/home/ikkjin/LagrMatlab/opencv/matlab/ +*/ + +#include "mex.h" +#include "lagrcv.h" +#include +#include + +#define MAX_CORNERS 500 +#define MAX_SIZE 700 + +// TODO: add number of corners parameter +void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { + // usage: [ features numvalid ] = + // goodFeaturesToTrack(image, quality, mindist, mask) + // image must be single-channel, 8-bit + // quality = minimum acceptable ratio of eigenvalues + // mindist = minimum distance between corners + // mask (optional) = bitmap mask "region of interest" (MUST BE uint8 TYPE!) + + char *image = (char*)mxGetPr(prhs[0]); + char *sum; + // int imdims[] = { (int)d_imdims[0], (int)d_imdims[1] }; + const int *imdims = mxGetDimensions(prhs[0]); + + plhs[0] = mxCreateNumericMatrix(imdims[0], imdims[1], mxINT8_CLASS, mxREAL); + + sum = (char*)mxGetPr(plhs[0]); + + calcAreaSum(image, imdims[0], imdims[1], 8, sum); +} diff --git a/SD-VBS/common/toolbox/lagrcv/test/getPyramid.m b/SD-VBS/common/toolbox/lagrcv/test/getPyramid.m new file mode 100755 index 0000000..ecae078 --- /dev/null +++ b/SD-VBS/common/toolbox/lagrcv/test/getPyramid.m @@ -0,0 +1,10 @@ +function pyr=getPyramid(img, level) +kernel=[1/16 1/4 3/8 1/4 1/16]; +pyr=cell(level,1); +pyr{1}=double(img); +for i=2:level +% imgBlur=conv2(pyr{i-1}, kernel, 'same'); +% imgBlur=conv2(imgBlur, kernel, 'same'); +% pyr{i}=imgBlur(1:2:end, 1:2:end); + pyr{i}=calcResizedImgMex(pyr{i-1}); +end diff --git a/SD-VBS/common/toolbox/lagrcv/test/img0.ppm b/SD-VBS/common/toolbox/lagrcv/test/img0.ppm new file mode 100755 index 0000000..816e0ad --- /dev/null +++ b/SD-VBS/common/toolbox/lagrcv/test/img0.ppm @@ -0,0 +1,3137 @@ +P6 +512 384 +255 + ó          +     +     + + + +  +    +   # + +       +          +        # "08%9+!5.(;(07.)2.#3*#+'&)!##).!%.")#%!!"$% "#   ! %)$32+):/, )$"%28)+&!$"&   ! %#('(%$!/!+&"1/34-1"6 5 *" !   +    !%       +   +  +'491F,<6($ "!%'!"*-#(   +  "2* # +#?64&DC$1$#./+2.)$ 0-"-A*&2$",/.?>::4@,5$/7A58T*37,%(("/72>,1-20>=):.8!2  % 5%;&6    +   +  " +  #'O$6L'CC:KTLri@Kf5QV(KHE<#E7,*#(+-FH2FB&?:0?C7CM8@<0JE*?F.99(-',?/6;?/@J2QY%W[!7O+3?8:H=?J7GKPdCP]IZmIWp`I]“YlÀvyyƒˆRxŠ@j€7a{8YgAA@[AKMTSHVZM[oXVbQJcL]lL]r^p‹ˆƒË±ÿÿ˜ÿÿ“ºÌ—œÿ—ÿÿüÿÿÿÿÿ±ÿÿ–ÿÿd÷ÿq®¬ÿ¨”ÿÊìÿËÿ¼ÿÿåÿÿŠýÿÍÿÿîÿÿøÿÿÎöÿ­ÿÿôÿÿÿÿÿÿÿÿÿÿÿÿÿÿ[Z]SIPZCOSKLULJRMQTPWSp ÅãÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÆÿÿÉÿÿ¬n~dYcQHWdA\mQceGHE31257=CNENI8>A;1;U3Bh9Mp,J—&G¢0<`4:J       +      +  + + +  +    +  +     +  $    +  "                 #"  .7 8, ,,)+)*+'%*#"&!#" &#&"!"'& %#"  !  # %).,*&-)#5).577 2?!5! ##"! *#$(!+))+-)&,#064'**$%!! " "!    $ $ +%   + + + +   +    +  ( "!#++"-0*- #'"-0#+*"# "  #)+*'* +* # !$*6*4;2-73*40:8+9" !! !+$22&)!$*(+1(2+0-(%17(9J*,A%"%"'#&/#3-1>(,(3:(,+1&3*%"& +  +   + * +  +  ,* +)%    ;(/E?Z*(",       % &  60 +-A d;!       + &1$      $  !!!$",'!"!"! &&(!%+ ,/%" %#);#.N*,BOZFnx,~c-L?0/8"QR(@Q9PdR„‚Y\rOQfAQ]+L])A_&?H!1;2;L84G28G1MJA3;?=A8KNGLRGJ`@CN==A6*3-11*/47:A7ZPD>7C@6J9CQ7CQ:F[?YW;LX>Wk:av@hzDhgZ`or^‡oaŽa_Rp†Ag€BLr@GZ0AN?CPL8NVIbWCSU.GZRZ__mq·’°ÿÏÿÿÿÿÿÿÿÝãɇ“ÿ‡¥ÿwÕÿ¡ÿÿœÔÿu‘ÿy€ÿx—êšüÿóÿÿÿÿÿlªÿV·ÿ¹ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿàÿÿÿÿÿíÿÿÿÿÿ¤çþUN_RKZXLU]JTYHTOCULHg]cɬºÿÏÿÿÎÿÿÿÿÿÿÿÿÿÿÿðéÿz®ÀXtwXdb`ZP_WQM^XaZQJA892246C?FGJH?@>449<>C'??#19'#,,+-1-,('!''%"!#'(&*%'!% ( !16!/6!,%.&-$'$ !6 5,I60@/3(7*."%*     +' # !"'  +(**5;4 +E& " " *1-G0I.94/  +   & /. ?? +}@ ˆ]9T)>/#="  +      ##:5-1        "!"%!&##"  #"!#')&"''*#-3%D7-`GGzm_`~F{y-ig1[c<;F?1=^G€cg„@R\A@U=7O<.=D.>1->40;A8?755D8B>0;45;387=247M@6CBC[_FWU-I@/<7F:GGCOS;R\ASkD[nJpyEoƒQs‚_†‡wbhgZecf|Ng}54rAKaBQ7@I;5@7"4.*7).6&>:,B@.6=42;84:-=>23@++/2);A1DAU^Ftr@DY/=H+2A*4@&9B/48-GE9GM?S^?[\BSWB8L6?M=JY9M]:OT64>:6CC=FEN_IG`MSj\Ucc^ˆhhžkˆ¶\‰²QlQ`vZ]{Nd‚M{—Xl‘BUk:JH7;B8?M3AH/29,-15*62)32         +       +    +     -**(3-*6(1&, ($" +       +   +     #% )($%(%$!# &05)G*'2/)+! + "    ""       %$)'-."&$#'%(./  !%# '!),(1!$&2%&*'  #"'$    + + +  +  +     "   +!0&2$ /)"P D"! + +  "  +49 9'$#'!#&!#-2!  '#(&%&#%!  %$"& #,/ 035'#0+%--($* $'#1"!(+$0!*!%.%5$>&D*)33$$&$"'!0&G92J  <2 GIFJ 4Z:L4O.O/    %##% $&+() 3A9"lk$>o-<%697>WNhR\&UZ/5RF;b9'S%$(    +   &,!77 +9$"0' (4 &  !!"%"'$""+&0% ! !&#*C1Jd=ac\hV^hbD_KDMIMN?A?1SG7DLC1AA+A0EP$GG"88&((,#3/0A45B0;>->B+FE*4@*4;('*4.*<7EON]QCI=<@20:,;A09<4?:1CBAGRAGPO?[SH`FQTNAEAJKDRN@KS?H]?\YRyg€¦`}¶Uu¥YyŒLZcMJk[LfoLk\I]BUY3UW?0%-7)(/#   !#    $ "'$%!' $(*#+*(%2"!1#       + +  + +  +  +  +  +   + !#$ !+'*'" +  '"!# ! '3",. &' &%$.*/-0*:3D:605/=/((!!#& " #'.$%/9#"8!%("3" #)*"+0!<#6"9/''+#*&.<%**'$,2F:8)'$<5!&>3'1'3-5$/31#E,!C/;()!    + &,GG3526,<.=#!  ! +%1J%CC#! &7#-M')@7$5="  + +   %,1%75A0"-#!-2@.X2L;.;!8/    !"!&!'%.''0+)*#( %)%#8')D*8QCQbOYEDQ/0:-+3#43!D=(OK:?CE-?4374334;335418=4FB=HO>:L>.:G3039/;;4D=8AGD7?DJJCMM/7?JM>faP]hwUs§\xµ?Yò2Qÿ7W¼=]cC\BD]:JWI_clNvCneFgBCGA…KPg_M«H¦rScr\j…of…‹_Þ€‘ÿÄÿÊßÿµ÷ÿÆÿÿÿÿÿ~ˆŠezgu‘d†Œev[bzN^nK_idk‡¶§¶áÊáééÿþÿÿÖ›²šl}yqk…¢—Œô躱¦£¿‰Ÿ·v¨œt‚gTTL=IfDMŒHX}STBMT:;P8:H;:F;9>513-42+61(  +        +   + !        +   + +", )0"1#-% !$,#!+-&%3%//5,!-,.)"+(!   +  +    "   +   + !$"!!%&#&"% *2:$ >0#2.-*).&  "%      + +    .%%'&/$!(" #&%"$"((    +  +  +  + + +  + % +!%, +!!'5 -& $        + #   ""$%!" #& ,%562"7@18=,49!+6+"/""!)!% &*")+#,("(&%,+&2 0,6)7"-1)"#1&$5!;'B !-!$("03-+E#)!-"1C2%F);9ODD945-,../&. 8#%# &" '* ) )3(!6"C-/>*/C(.64=B +*#"" % !-(06+0-/%/13##,% &%3!9!*!'26:)4I%+++&   9,5QKU 5":2 >+ <*?2%,hNG\>E?>!Tn=k$#S&'$       ! #!(!$#$$*+6-7-6:5S:T+B&M/C3 -*!674=HAEICAN=8P@0ED3FQ;JJ)1+((%+$(<6;I,KI"A:36#370NF9/B8.5--.&(,1&6)CM7JR93D1+;3-:,=@+=C,9@91;64B<3C>-87900D53LI:GD;9GG5C67;9<;H;e†?m”BTlQMbpUpnYŒ^kž\p‘JZh6wi7Yi7Fa40GE5@EFC=HSIUeMU[d?UwVeibWSA5K=HK9?G;A59E;,&+2(*&+'!!     ' #        +       + +    +  ("))0&!-)#!'"#!)$C$A6+98' + +    +  +      ! +& + 2 "%$* +           ! +..(%"    " *14$"#$'$1+5618@5 :2'&0++,$ ",2C6K9"01$1#)0$4/"1-,*$'(217=BQ= +0#!(')1"1"%0'. -23!9A853,0&% (.6!!7,4E!1L#8%8364;'4031, :(4,D+C1>7E/C-?BI¤1G$#(-"0<0?81-'$8#!"-2HC*72%/ "5"6!(<$8/".1( 3*$2,%%8B9K  0C!DIF'% ,$G)LON^N=C"8T>Gp4Rc 0A1,PG77          "$$").%1#,/!%14:*5H1Fj$\j'`e,G\';O#/A4-:=7:D9B5;K05A>82;69D:>B:B@I;><4U`1]r;YtL_’P_ŠAazOPtaUdaTk]^xVg{Ho•<|z3hh/NK7B<7@D?=KN\lQcpEvrN^c`]hAOb/SW9.742H1HX5NaIMWJ6F?2E00:?(:–[në^ƒ¶h„º‚‰‰}x„†‘~€°Í±Æ×÷éæÿ“±ÿƒ ÿ¨áÿ¯½Ì]zNN_XQmfSz`ZnNcoP\wSnŠs˜¦ž’¹ËÅâùÿÿÿÿÿÿÿÿåÿÿ´êáØÙÞÿ½ïûžÂ¦ˆ—€k{o{pgfZU^=JMBCKLK\EGW>8E66=77@::C:AE<:K85E2/D3 +  + +   +     + +  +      +    + + +      '(.+*"1$+$"#*#*%%++!(6%+9/!:/0) + +  !  +    ! '",+%&' $47%;,1)"+%)/ &*  "   ) !%         +   + + + +     +   +       + +0*%2'#2! -%#".($5+=*+383,-,"*     +  + +        3 +*# (!    +  +  +  + $ + " +E(#!  +   !! )&   +***)%:5*,85%$+"+ &$%,!(F*6?.66+P9#EG$4=$5J3A574A,9 0%)+%0!25%2-2883K*6-/(2).""3),D)O120*(4'%.),-3+)4(.4!8@*D4)7#."#%!%"%&4'179B9V*+A(*A$J9&Lk?D8&*$<"9"J"6!2  %-50$ %%!(&"& "#0- E;384,:& 1 #*E9XD"c4/&!-*21H56U2JB:MG8.?):    + $ + +      "$.-'.+1&.;941B5+8<5@=0@33=+05=C$CA'A<;:C6EK1pb7_h;RU+<:+'"'(#'+-1.:JEN7KT1F\'NS+HP4_Y.IA+?=/MU@R_e_xi…YLWB[J9RB1@B.<>1@C8EI3EJ6GIDAFQp@_`OdƒV‚X@T^Poi[s~HyZ_uFcb;BK=BJ>KQIfrRþ·SÊžO”TjtTkwB\o8DE,+61:F1^:aW1MH.C;+?EgTdºy{ hu[‚™[†¦r‘©}–¹h¤ý†×ÿºáÿ¡è‹œþƒ©ÿ†¬žft:xƒ8twGUxRUoGWgJ`k^`}zo—ÃËÈÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÉâ’™œ…’}{€pUph\dNTZCSU9MSEIYHEL<;0752:5055   +     +  +      +  +  +   +     +  + $'$) #)',%/ ,#$     + +      & " ( 5A'73#30$)&)-%,!"#!   +  $ &$""        + + +          +    * )%#!'#!'%(" (+(.&.)40,4*2'%6.;10), '#   +  + +    ")( ' ** 0) -% ?/(65*0C(% +         ('N,V  +  +  + +& %#%%##**  &(%$-')%%'1,*&$/&1#34$8P)0S>0E3,6847-43(73661,+% !.'6&*7549E%15$/)&'1!#,2+$'/3<KH<49)3206@16)/(30#19/7(*- '$#/*#;$+&#$)'1(@5!8$#")2-#$$)$& #'!0)9#-E$*P4W7P', **1ff1L‚ $O,I'7&)!&-:'4=3>1R`.jX-V#'<      8 > +1% .4%B$)1@7+ #&$&#*,G9]>$U>'DI70LZ@bPQ_8TS-en-8D$3.%0*'47-)3(,'-/(5-*/.-.,6-7B4U^8{\2dR2KQ8_kEgjXf]C@I,-6.7 #'"1-*:73/:=8A@-;K%:A$8G5MN:I729:/?D5H`DeNn~IOPRLIOQ9KE5VB37D6PR6@M7ZgH]eSdHgl5PSJgCOX5WZ1XZLTfXyl\wh]x…kzŽš’˜{‹¥^‚åi—ùj´ê‚ž’kš¦š­°€’j^zKgKl”@dwBXkPShQPhSixté®·ýùÿÿÿÿòÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÖÿê§«™€t„jO^\I]MP_BMY?KX@CS9CM;?D36B7081,43(02/3338./3- +       + +  +  +    +      +  +    ! %!%)+'      "&1:$>/ 00&2+(0%&( !!! #    &,,-   +  + +        +  + +   + +      +( "0#!!"''."%2%$-*&,#'#+#'   + +   + + + +    )$'%*#==?U'.F<4?@&G$       + )$):7#L#4"9G      ("+%%))&%   ! '( ! # .347882?6";?6;G?UD1TS XMGV ;P:U6R,K1G-::0663-/"71!5:"97/6:+,**3%;!,4.061 +&!(9)<'5*52A0<-Ag4+k70O9GG?99VEKCWQJhlNUm,NJ)7B'7P&PU(fT#NH#>9&56#42--8>:GKPiFmy@bi=9NQ:VYOdS?>8#)( (($($-2)1:)261<<3)12#5&2(.J1;;4:./928>?;CV/Aj1GM:IMAFIC@9BE83=9BMCOO?/T]9{v:ww@›™?x“=FWEEWSJ^OSdO\sOW…_OtkXz8`c=NOBRWEZSV}\VruH€€B…‰X‘§†¡åc{R[FNdIKbLKnJQxERi-Nf/Ub/KUGHbR@YIKc>KoBWoZWgWToMJr`Z„ƒm®Š«¿Y³„lg}”a‚œkœ€`“Ÿ[¡‘bˆ_Hh]Lj`JjOOlG`oFktKat_ŠÉÀÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿõÿÿÿÿÿùÿÿÿÿÿÿÿÿíÿןWnbE[SITNCTHFTEGTHFS;?O::E29@158+03./5004-&..).+   +   + +    +       +   +  + + +    !"          %*#"/6#F(F/)66)')&.'$%!  "#!'$ " % (       +  + + +         +  + +       #"($!               ?,F9D6(@*/&'*6&>'  # %  + +  & *1'"&"):!-*  +  + +  +2E+5<'# + +  "  *(&5.$""(!!" *$<)E.<%:?"MK.=bFFa>JWA>E7>G- 7%$)&3<#:H8R%GP"SSEGOE3B$38(&- "()!*,39A#DR!.>/9(-%!/&0'H8)/G/6M13K(&+A/7$#.-2'3*.<1(E!.   +  +   + +   %$! *,,<=7?5A]*(F&)8!4%%";'Q*J!)HJY-8z GOs{\|*-81)   +/;EP%S\&YQ,gbP["7D+5E>9EM(1J'&7!)-&;2(AANWBu‡Qby9\d7JS5E8<_MCz8y7SW2-4)*:.4@1::T:F\5QDAJ:PEGhYS:E2+. ./,'#")01)36+6;0.8"0+"$ '(,++.90,/5,CC5OA3,0:%0>98FGC?7=@EA7=66E?BWY>jlJ¡•bKx@8<6Ev’C†«_ÐË]¡«kx btŒp_{S‡ˆ^|Q_u;ew9bl8^e9LfFPh2Ic/I_)Ol2Uo9Kj=O`?Ie@N_C?[DHfDJlXLvŒXŽÃW¡¡a˜oRpb\g]Ga\^snYtlDkNH\IWhNWjLSeVo|Yv]dx šêÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿúÿÿÿÿÿ°éÿ…·Ûh~T[OCPDDRIEJB>FD8HB:M>5F63>1,7/,9.99,48--/,'-'%.(       +       + +  + +  +  +             +    # %)&&!&$"!("2$;*H)J7&19---*-"% $! "'" #!!"!      +  +   + +     +      +  +  +       + +        +    +   #!   >/56-5<+,(*$$ !$)'   6 D@EF+B 1   +   +  @%7M"+C.#5 $#   ! !#)",,07G<.>--+-7$5)%5:%33&36 C;3)9N-3?B@<=C6GF=7D9-.,'& ;3&!E6848OE3Al64S08=*3B&0",(((#&()*6*<)6/1/#,22.=(B 2[hFon;ET>"<9!@7$M@,A>D6YY6]QO^QTQ<^b2Vn>SrYxˆKk|0WY"u^&U\6:H7WN7`k>^a@R_?T_IWqJ^j//:$ & "-%'",,*,10182'/)!- $+&'$1,,:5,7<28@DCQ5C;#ND(XX;Xa8GI4A>3??4SRHPQ\BZ=p–4Pa1=:@E;>D=>4=8AKY|W‚²H\‚?c|>ThB^jCOj;Rp7OtH\`d“[mŸKr£hm­™zȨ~¼t]sFpdHcmE`[DjIQiF_vR`x>Yn0Yh3Qi6Le3OX1JS2CT8Ib:EX9;QHE]E>C;EO8I[;OgQ_pŠTn›Sq€Rh_O`]BWT\tEwHF^DEcIZpDTiEXeSXomaxjuˆÍÄÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿéðÿéûÿÙÄ킆šYiaQWJBMBL75>2*806.8;129.+1'(-#.2) +  + + +  +  + + +  +   +    + +    +   + +   +  +        +  "+   +  +  + !$ # ! " 1'='I+!P5*387'/0*!#!!!$ 1&23"0        + +   +  +  +   +      +     +    +  %  +  +#  +'  +    + + 0+011779)#8!     % '(1!&C+D15M7'=5'%     +  , 3$ +43$K'J:'28 3(&'#     #$*/$=K&DU/=RLACIKC!HJ%>P!;M(0M,44-DH 6M)>J+?T->J1DI#@C;F$:G5ED#ER8LKQ,CA%8()%&)'1"7%'"%10 ?+ !&*,$(1(!'$46#0# # "!!$#  + +   +      & !"!( ($L1 +  + +  "$,DA7XaJadL3L@JS5Aa6Lb;VQZY4P`3HO;S`7IO4%3A,2P)4S-PR1OU/?U4J]?Q{Bg^Ae;K^5Tf4GY8`VIdeILS<5MG,DN-Ce,LH$5%,*!"#&*$ *.'+5),6,'."'%%+.,%32(:>48D4R0GY8H`2>nBB4@?7E?DGF=DA0FF3XfM]‡OMfMjlO[cIHeJA\9Gb6bs=bvN^pTNsJZ‰K_‡yLt›IwrUoFFaHE`3C* "64%   ' '"4+&>532@05Q*6U59O*3W-5N(2Q)6R47C(6<&@8,$D0$64614=R>3D/@J+6C':B)<@5*;,*'$-! 2(*.G0>(**.!)+! *+.0$,( # )   !     +   ! ,#7 , 3 +H*+%) S$5@ ! +    + + ( ( * .!+-IVPcrTgQ..;42?7=>>2IA8H24B4EZ?O~8€Ÿ3——2‚k1KK76>>/94/3B49I835*.30C.E@:BHU/7A55C;7H:@K59D43:0*2/&,-&+("%$'&%$ +  +  +  + +   + #  + + +     +     + +   +     +  + + + + +   + +     +"   +    +*;?(R.!V4/4@3,,0#  #$)#$"&#"!$""$%" "$         +     +          + +     +   + +  +      + 2#    + + =A. +-1 %, +$ -,%+$)"$  +%&"C&;&"+ :1^J!WZ.MG*R/ &     + + + + 40#"-% +   +     $"(#518%LF$7E-89).3,00.&"&0-)0("'/!"@/%K;5D$(@>?1- ++  &  2 &   +!$%  +   +&,,#,#, 1 %&!##$-9DQGa#>S.5 97;V3RXs`xM+Q' oK ŽJ_,iG K7O060B   "!HHN`f]>\BE@#<;-^U-AR6/<)-G::M=1:1KA9\L4ZP#GG/SI6i;~h+TN-NI.TSIubQcpHTdG_jIBMF?AS48K9>3??1BD.@;+42+8>);:#4;!51&1-%)5%*)#"-$'.3!49'5;*8:,!9+,1/B<99JU@RpYiD}Kmˆ2n[1jQ/?=-+54.9-2:-/.738:6DC:GF=O;Li;Kw;gZOq`Hc];[FFQ4LI1hR=LZZ\fUUaIE^:GZCbdHRj;Rf7Ih4F\4Db=AkI[A;ZG6PU24=+01%,+&$-& +!%)"!%! +  +    + +       +           +  +  +  + +  + +  + +    +   +2 +, $  + +     '<I,V4"U@22J6&,7$!*"4(./%("&###!      +        +       + +  +  + + +    +  $  + + + +  3("S.8$&2#!'" 5(752@#7/$21!)&/$ -, 1#91.;4.'4$(814JJ>\Gbh11\1   +   4 :)-+#$!!     !%,/*,50'!0'6/66/./#*0+.@=$8N.$D2(F+(:'!4-#2& -!17&>D"AE73('2/# 3 "$"I9$4@?MG?HR 10&*&!$!,3>3'%   #   *-"=!#>2%8*6E%H2 + &< BLCV4E )5 *'/. +    ""!$)/!4> 5IQI3GK .:'1@!A2c*G[:K#0H+$]@.k@1`(qw:f˜(6g,<'!# !%")4AAOUNTDE^2V_+;[;'H1#6*"-6$85)*,'28LR5Wc6Lf8__?u[RŽE5G=8H<=PE]jO_}KGcUIPF9E5AR51<07B78G@?KBEH19A,:;5:E15@&>@&FK'5?,-;#10&)-*(43-<4+,2,).&21'ES-Vf9BDL@BdCMaOib@vL;d¯­N]5FTGSkQTn>Fb+K^,F]eBAdNSyCVhKXv¥’ÈÿÿÿÿÿÿÿÿÿÿÏÿÿÁÿÿÞÿÿˆ¸ñipQbZOaTPXA>JC6KB5H56E28/7G'%4 (5(*@(1'!$"$! ##&$$! !#$%%   +     +       +         + + +   +  + + + + + E2#-,6+8">"-2%(6+-,-!<-(7-2725!37@?BK(7G-=!$!-3E$^1l** +I +AE7@ ,( /B( .N D5E)H(3"*6097.%!   !'  !   !" "&&%%,+:<''1'&%#).$96.5:=2/2*(!''%#$4,(#&10:H6dO(TY"3K5CA2S;,;L+H<2EG9CG0BA,=D/BE,WC0G5-&+)18*9<(48/3@<7SIRnCks[eŒŠÌvyQkyYdkArxHm}Pl{QnxFf{@oz-PZ-Wi/[n4Tw:Ie:SpCQkQEaCGX4BX1Gdnÿ7ù>mV4BA:HUI^€RwxsŒNMPE>T.FaQHbœ^Žÿ]¥ÿlüÿ„òÿ{°lAS65?.2=53C90G>=RI?]P=ešÍÿÿÿÿçÿÿÉÿÿœÆÿl¡ÿk£äbƒ›‡w\`]MCWFFS;@H<5<=.<92:3,=2/>+/5()3,/5/.66/8317+(-%*1$..#&-&#. +   + +  + +  +  +  + +  +          + +   +      + + +) &,   +   +  &5B' N2'DA1&7<$&( &"(0 3*"-')%%''$+,$&   "!$"!    + +     + +       +   + + + +  +        +      + + (&*"*)/> )R9>?'.3+-,$&A"*7(*%(&(*F.)=Q;:X;#d F  " 2 + -?#T84QLJH<80D.=&(60'<"0+$$#(6*!)+-#* %$ ($   $,1'$&/%)$#*+%-*,37:4CF@BU64L0:=L37A,)1#: #0 *7U!L" 7 *         #  + + ( + "      +      +  %!#)"*'$-- *!-!''9.L+]U0%.!'-* IIRF7A*<%+A3)5=$.5+D/124;#&$ !+(3-%.)'-N,,J1/7=>ILWP9]A;K8C?)_O&`C0M=?6=J1?G0D-1:/*835D78>5;?%9B&:;-3?4MY/^x5Xd=Th.d~5h…A_‚=Zx=Lc8?K:=J67K:N\=J^;JW:>K?MVGAS`5Ny-F†9R_L^DFW[>Rr8R”0S`FJBO§K{ÿiÑÿdªÿk ÿ‡‡È€y¹Zq¨`oqi|blwF]\CKS<3>34;22:787356055*;6&(1*)5.052+00).-&)&"+%&,&&.'$,# +  +  + +   + + +    +     +   +        + + + +    + +0-$#%        + +' :J( E5'883,28(!)!!*#,) &0"".%&&"+&,*)/# +    #     +      &    + +  + + +    +   +          + !+#:+IX$>T-$:.&"%."*R;+JU8K&#>(!.J7L&LE" +7A3@'L$+6-I8;.!./+$&!(,$4+ ,''!$*5@-/A;%`N)p](dS:SEO799NH5w^TH3GN8LUGc^\haXpaZrrWŠ`W…OoUˆ•U—O’“;{l.z^)IM01O13G9;UEA_EMjA`eElm;b`2IUUSkYTZ[[TzVXwQ[P>H/->,-6+88'8B+:I4BJ0IRYhǶàí¹µ¦¬·±±‘œ–owtkj{wfqv^mM[kAS[9=E1:>,2<19=1@:-Q*;;;0-2&'$""$)*$+&!".!),)    +    +    +       + +       +    +      + + + ,'>,I/?:45DE1313#"*3Z(%IbK9VH"08=*=)*75"$3 .("4%/ ,#0B*I&8%-/7/?%H5(>4%&5,&$.)(+%!+.;$4'!&$ %"$&" %  " ! (!A(,7'::5%9@90K#      +     +    + + +       % !!$@8=0(-+,:)8 +!=,##""''#&+0+..=-DgJVyMF->G(+3(#'%1-:95:64?14-,45-.,13(D@LYEWXIY:D^6NQ;:J(2D&1K=9T90D)29)0;<0@K9[RQgAcjDKjTSt]cŠh±‰™Ãx†Ád‚´Pw >^o*4=(+732<:8<@5HY>ZaUtXSa89H%&;5*KDa|MSvIGn7]Y.XS4MX;CXDKcHWeTUl]y‚VyV`bZVRB8A.:8)=:2EA-LF0HC9NE:PN`y»ŸÃщȾ|½a±j‹|kqhyj]lbT`U[fE[`?TY/KN1=E,8@2BD3hH;sS9‹N1L<,)2/(8(24%36$-5$.2"*3&*0&   +    +     + + +    +    + +        +  +     +4(""& + +   + +  + &$    + +! +: A&Z1LE.=@:*2-%%#! ""!%##$% #    + +     +     +    +   +      +        +   +   +  8J<$7R53J< <1"*$+#'+:.YDTR!A48$ &-3'''*  5C1<8S09K",?!7;1IB,+8)**)!!+!*&+%-,"(&+%$#$ (  !'"' ! #2+?>G7*:C"@@$56235=8>.44"",'.2!'$(&)3.#$ * $",+$$          +  + +  + +    +  +  +     +              )#"" ?;."   %"$#%%!"'!"%$ &7".\-:c5=-=A*/0"&',%$$'BE1FI84G:65(/$"1,&@O.DE(<8+<>$91'22/)482C74B+7?(_r(‹,wd1uxC\nE3I>4F:3A@(5*2.&63*5;,9L,GQ%XW*MR)BL->U6=V8@46739:'3B,.B-773A@QLaJK\:@^;\zGwfiy‘W}šLv‘9_{/Rr/NA'9+&8-0@1OQC\RE_JAY;JY;DO68E66>=PDHcBEaL;060'.,)0-*1*)3),2*,3+-.)*' +   + +   +     +  + +           +     +  4 +''(  +   + + + +  % )   +% +6 J$L.$J=8?;@*12-#'%"4%$" !,&)    $    +     $         +  $          +    +  %8%-59OcJOY=JK7BKHeNhY‡¤Z•SqHFDDCA8>;'A@1JT3?,45 <978BH3A8UXMcjikoX`sSVo_T{¨~Þ¹ûÿˆ´¿‹ÿ´j‡}UHnNRa=Z`FlmUYiMU_PQS@HI`vŽÌÿÿÿÿÿÑØÚ‡‡i]ujH`oL][:KS4FI:CG6GN:EH5AC7K5>J2?eADT::..*$)+)/*+/(*1(+3(/3+*)%!       +!        +      +    + +   +     + 7 2(+)  +  +   +    - <U+N7$HA7>@8230)'(% 8 )!!%"( %"$*$)&   % #   +!%  ! % "  E ‰F-Z;    +     +  9=@1<1,+(0%QB4C! -!+"+607,    +  #%*&,+.10*!+" .8!4F'!5&()&'$$,","3!%.'/8 3.'$0)C2;.,"$"&*)% )-$0&"$'97$@D82HO0;E 5=(H*A!!# !# %!1&%     !            +   + +  + + +   + +   + + + + +  +  + +       # )  $#*%-/. '!.3<9#',42+a>P34$ #  ) !! $  +!>0!@@M;3+*5=87D56G23D4B;DOCQH@7;A1-:8-6E+:C.95??<>::AE4\Z2PY,ZT597*LA&>C;1D?<7<.<<-?9*5>+2;-2;/1(-1%+0+*88,K.Ib?D^O>a\8SS2F<-A018+7J+?S/TpTBs[>iOcr?k`E@CI5F;(5)+,%/1().'.."60%/1003/21,&41.>19KEBYWRdL?OL7IH:O4DYQ\r\caw“sm¢`qž>`|2s…4v3w‘2o4O]6AT4?N>XcEQ_:HS.;O-L])=N0=TCCUXAdbPefK_[;SZ:X­<|ÿqÁò“úûÿÿ•ÿûHU`FFXZRe]^x`pwXeoNjrH^o}~ÁÿÿÿÿÉÿÿ‚±|o‘[avPS^UNbINP86::.5;,8<4>8;>87>8;C4>G9UL=sI>[H>sK.A9%1.'..++2%+)'((4&78--        +   +   +  + + +    +             + ! 5 2)(/! +  +   +    % +* " * 6 C'O/ C9)=6::;6*03#$   %=!-!$#& %%'&)*&0,((*#!$" +   +    " %#X,%AT!'+,&       +   !W KY AG"9=/4/'87JPVc++Y&%>$+'6%2;!>-$C-G+   +) 8(-+#"+)"'/$*0*./("6$#)-#!)'-2>=/946-8!*9 A>6@0?%&;%5483)9#2(()3%!& %"%! *!9#3'#"$./ID38 &#"   $7$H,-(" " + +               +  +   +  + +  + +  +       + +       !#'$ $"(+.3(# % 47,6Y$-U1S8@;H!6 "%! #$ :6!:D&265IR+KG&A48I77?1DH6*:2/:-*3-)0.+-/<;9>I7=WBM`K9TJAXDCT,QK.XG1A@4GR-6A7/5749)2:+88,>E&<<%64&31).+()850C>.89%3>%:4/0-*2*37-GM:`PI?J?I_MOoT=mB9d05G237!22%E?$G=$B8(<<&48+&0+%1)23.01:68N4;d/AY@C@J=;78A4>R*?Z7L[=glPmuQt\YsHSsS]˜Vx©Uf›M`ƒ=Zd<;PCAWCHb;Mh0Q_:T_8JN,CW=>VQ;BT0GL8KE4A:2EW5QÆN}ù]”ÿ”ÿÿµÿ„7J:D[MKebKfjUnef{ajwY^~›qžÿŒàÿtœÎYqwKd[KdOGZR=PF?O98?3*110<5:@89;61=51:40==QGFqIC=7C70)24%&)# ! ##7(,%7%!6(/($/+!" '%-*70+2"*'  !"!  +   + 8/&5C,(4       !. '61<QK<>PKB:;925.(0*<<MI,R 11'?K;J!7I=GBnW)!&!% +$ +(0(+$(!!#!0'*$:'#:!3$',+"0 '(( +0'(0$'055&+8*=<6H)5@%-3 '+,9&/;$4:1>"'/%/)$ )&3*"4-7$"!% % ,71%5)0 +, %,"!          +  + +     +  +  + +  +    + + +      +  +  +   #% &#$$+0%<;+&'," ! "#0,102,.$+ "13846L0=SKpt4F\3F^3Sj/N\41I@,=C/5<26&14+")* '#),-(86*?>6CO.HM(3D%0M'AFGMNL`7BF+;D9CO*CL%CF*:?-MG2MI,ET.@F,5B(3:#11*79/8?)35&13)8;'.;''-,1;K4[@8F2KU;EMP->D+540@*6B*RY3LT>Qe7Xb5hg;TP+3;&%.+)6.KM/BF:;B867<;BC1B515*001,6>5?C=DHU_SS_MS[GJUB1CJ,SU<9EMPEO`ARqEYqNl`TdyXwÒo’ÞqxpOdTFTRLVHJRC=ED3G74<,)3.,94>C9:@179069/"+1%11 ,9 !4%"&+&#!3+)5)24!.7%*.&(1 -&3$ ' ""!       !((%!2&,(-)"   + ?RJ1B]=AR8,X.N)$,5/,G5CG$4/&/3%(%%5&(I-=3"$$#!*!'4)8!/ +-* -$+ ($&1"4-(A0-?01*/ :7)C=%1&1,-223/"##!, ;*"(.%   26332)50"" "( #" &3)4%#" # &1%"             +  +  +     + + +  +  + + + + +       +   0.%) )!&$ #! $"&'!1)/%(#"*-$5$)E%D9'C9:/8P)@T$1;;A;3A?/Q,S]*ET:FlC@_EIYB:K3,17$--.3)@H+7F/.<'6<,6E)1>"4<)49LEHcJPmGVb;9@.0/474:3UK6Q=JP.GI-G<=*#-)4):FJgI‡n;VMKDGmRbŸI[J494I87I;?E=I8@Q2@^4H^=Scad}\g„JifQa?Q_BN]AGS=GN89<3+2()0(+591A64B47?14<2F?ATCjA/%%$"'%""$ !!"'(0%2;&5:& +    +    + + + + + + +      + +       $ ) 6<$$D()C2,-20+"" ! &)%,/&(,%',%,&$!..8+7"!7$%,'2(%%% #( ,& %    +            ""#!' +# 1"    +(& 0@543M(2>&(;36'$$&.,)#!H7:./.$5.#="922#@ (,:!6+2);&(-"%"#&!'#+$#'!!$%)/!&0("2'*3.!1*/-' !"'&$ 1!5H-G6C&7&-+$=>!!  !   )  65)# +/0-+&"6%   +        +   +   + + + +  + + + +  +  +  + +   +       +   !&1+4'&+,#<"+ -!#   &**#%%"#.)7#! 3.$95C1H@/@E2GN6KI>N1BC-?I7CN=EK-?B*:<*:808;(;5%43+=64>?.=P09)G8)@8+DJ292D9 *-)*.=(6;(03)14$10-4&20,'.,!))!1/,:65@C=IX>D[EXIZ_,]_)e_,>E44=@6C91@5:=.*:%0:47FA=Q;9M{qKc]X;D;B;>H"&-%#*!' 9-# $'742C,9:'7O$'C+&'.%!##&%/!1+,-(/--*"#%"  ! "$5G&2=L'.<'G?"";/-"!$)","   ##   4",&"$'*".,           %#+/""&$#%!@4   "*( &!-06 4B3;2?%ST/VM32;.963>A<1;:?E76HA4BD8>A@J/F+GS4YQ1AB:EG:AM0;S(FF!@S/OHcCTi@Xk5\a7^m9np12>-2;'GN/n]@F:VUI\`F[wVzh]qLDUoJc¯k›ˆjdN\D1898:CE;RHA=D72-3-6:,56,.4D4CVQkGPWB@SBAQAAR>7HB=K=@K+=>'.-'(---1036+2519:7H?IA?C5/%$ %4:'-:'-<'-5+         +     +  +    ( "#       1>"?+P2P7'<:,1-.#% !"#'2');("%#*5 4&)' -.#+-,'"                   &!.-(<1") )/6'"1(086*+09+)8#*%( 3/";& +""?'6210 >%C*4/2&*,$L&/J* <8" )/$, ,*"+#0%$%   +    :O,<[;G1H4)"2+,(  " !   +G"!:..)" !0 .%L2&@X04D8H7)98),#*,),+/9&9&%,*  +    + + +  "".  +  "'! +   +   +  A](@  +     +        $!'%N6H@A3%5*,$)&&.+.+#   !((-?,3<#(/,).;>1D=EMAIL4.991?=0:BBL<:CF"16",(.0!,)!'(*%.(%-+3.92BJ%cW)IJ*;B1AL6AX03;/%17"0+,D0,@4K]IXfCSi@k~?pƒNXˆ^_ˆWq—\y•gd„_RxUGmOHvI7R10E26I-0A+.5$(/"(4!&4$03.7:,-.**(/ )0$*1,,;/0B5DSGWmqr—sš«f{‰;:?.%24&6.7=*9::;KLFgPVl?;K==?LfaK~nhŠ•s¦—RwjLdcd~”HWf8B6).9,6D@>DB=D=7.131871:8+/8.F$      +    + + +   + + +       +    +  3 0""   +  + + !$1 6%5)D,"A7.867,-/&##&+"* ,&&)!,)'(9 ," )#,*'&,,"5-/(4&6,#! +  +       +                +   "(#)#/ '5$6: 60.<-)'4*$%( JGE"44!A53JA;%-:#.3(,;.8+ 2#)<+*%5"<92%#$&&  "      " >bL5g+21C!*6%+7,"     !   +D#"*@0%+ '!%"4/,I/,4&F,NC?!G<#8=)5-'483/34)0$"! +" # $   +  + +  7)FU<<4.#  7    + n4€8N,T,KC>\U!#& 2        +       +$71[e+Cj!&E $2;OB.17:>/BD75:513,75=5>I6C<6B/70.35306305#1."GC"AR5;483>%2H&@F8XXKXzIQe4GQ8JQ=DH6@;(12*+,.9A8=O7.EOFdGLxFZ~QXŽJvŠH[w[W}kQsdCcED]/Ib5E_82L*8D >B#8A$,?(1;!35./"66(.4*(-#(3":6%2,%*+&$)2*3:4GH>_vTr–i„gpR[O*@4'C@18@2c_1B@F=N[JQGldEnaP~‚_šhZ„Oˆja’M«Y{‡c†sMZ8S[:b`7UP9BG3BF,45+5;48?(97*?21F2.?+"""$!#!!)0'CJ*=L.8K%       +     +  +   +    + +  +     +  +    # + +     +7 2)-' ! +  + + + + +   +#17$='F-$<1(532/,*$% "!'&$&%))&0$#('.!33/<%2&!% !% #'4&!#(1"/.&#$!  +  + + +       + + + + +         "&*$$6, 3E1"8!9;#>M+<0%$'JAN*4N1:P&NP"AX&=O/&V3 9+.""1)2EH/2P1+9(2.-#<02 !.)"+*'#&  " !%! >U=7gM';#@="#1% !&* + +   L/F:6$$)#0*3(4<&<0)I0)?31<-96+B5+&8(*?&)2$1.+!#%* #"'.*!)   +   + %"?.7 (?(]PEX?@SR>/( 93 RAFh4)0+'101. ?9-1(4* " %'"#&#&,*#55??/=#==& .'((/81@F=;:4GC/3;848?7=81?,(;./?70A7;H6GD-(4,&,8:A98H$$+#!,)$D.8],`^/CE/8:5=D7Q[=>mDG{R"Fp'3J0-B<'II:GA;^aE~IRtIOvYDaN2G<1E6/>/'9+(5,*6/3E+DD'33+06-17'E;'2:)4<%//"2.'>92<6#4@"9@(>@1.=CB68Gop=j]UacbOfnIii5Pl3Xb=Pb`_cM\eq„jrh~•OOY/,,'(). .2*2474495:<=:8:2552:B>LWHOZLO`?GW=FQCEQCF_GQ_6GN8DF.?C/?E.=@.8;/>//8.0=/. !!(*!($(%#$.3H,?K+?G*  +  +    + + +     +       +   +        + + + 11+-1 # +  + + + +  +& 2<'N-M5%@<*1619''&%&$!!'!% )((/)'% :20L'4#")"&"( %'# .%$#0)$""# &%&"!!1.#! (6"4+"'"      +               ))#4+6'E-%@6A<JJ+MF06I(?<#:!-20/:=0%6A?.6?)9590=.0)".-'KM25G:,.*" 1-,$17 "!#"(!,&2&0&0. "%#"! # H)XKCDDN052$>()'%!  +    I),D7:0%%  '5.)$*-<+(3&+-+14&11 AC;E()" ##',!45+.# +%  +* ,4:(&= DU)EbMIK8(<%K\6]z&lwY\ BZ.I\CbjC6nC&32-+705aP%?G"#*-3 #"!  &!-    +  '#&+.$(C$CH)>?,=<"6.#/&-).)+*6,--#*51/98.54"03#)$'!151(@9*<7.C<360137-21-0.'*/'*0,0544>*=:3B(JA$/2:I?,;>56 %#BH=TaJH^.CS0ahA{|=aW/U]8J\:Rt;@`>HdOIleB~BU>M#/E"/" (/(=;GO8:JN>BE5?@1E;2:5.<5'3,*.)'&+*-52:>.@/*7'.;3QOBoj.F@)%0"13)LL,MQ6[_/JG-7946=*-/./5C4J[:O~fz€€ys9NM,E?2AF2KnKx_Qw[`v[Ud`$>J80514%'$*!$!  $ ""- !0*#' #'%%%$-!$!)#4,-;"*8%&+'"' $# %,5*3:"A%!6!4,',0'<83A4  +  +             +  +   +  +  %8%3B&1.+(<+#AZ':D2JF/6O6;<$#42.1+->#+2.)83:I.=*4I#4E-5@$42'"5%)8$2%&,@:BF"5=:2J5J?16..6;0@)E7> 96,#)%.:&* +" F290G<&=*&) !#!"%##  + +D%)?87.3*  % &!&"$,$3,52<!1/?/ .!%6"184A/C*B'G-E)F"./*=4>;FD.D4%3%(B8;Bg9[a+NG)A>"@B9U#C" 2CT(QX6iy,. ,,#-( '%'($#',2-6C0,>40:3AN.GG2;=20?(2:#+.DA*MsH]z1CW4C^O€•bl„4L_.G[-Gk3Ou06+-') #/9&789I4JY9**B2%2.#/:-?>VDNT=7H?6HF=RDDV@IR>9NH7KIG^CDR9;M==NC>X@DP/D6+G91nJ/U9#83(A@,9A03>)$-)!&%&,-3%/C,?I/    +  + + + + +      +        + + +      +    + +   +2 0(+, *   +    & +2."B'H21>>816;+*%!#"!$!#%&"%*".#%"!% %##*#'!*"'%%$& % *-'*.&*!)!("#%%) *&%6("#7!%/)/'"12 +:-#0. &        +     +    +  ( F(2:!2"!%0896)()* /7#2KB=9<8G4/E;!-4#$2$4%+*0$1;&?"+,0--3/9,46+:@)*6%/;%(+# $.;BALRQ!Ef#7V!<_6C1C/-S22:",<.=%8"+$""!""#,-!(')#<"    '**2(   %#"0"(!   + I"$80>$+3  $*3;D- ".!!(%(OG/TC.B9)"-"%.)&3')!.;',:0 01 &/+5!$@&.63;02:-32%%$J$R8d20$2-@)%    +        &'"" &#",.21>I.--7((GABCM[3*A(&34-=+ 4!&.#')-*3/#1(-'* )'%$+, &'%5108,;8$60$))(*!& -2*986'0,&07,6A&74075$,/"6(%0-;&-G/7D7Ht5XYeGq}=jcC[;^[33:.*90-C&+:"'1.4(+J,+H*(4D7A 0@/?H5-C;(E$.D'5M*KV,CN+C5PIJO17+.(357F6;C/651*3H,6d1KZ?RA1936@19>-7<59A3A=1682322&..2888@>;M:AG6:I9AHA=HB=F:7;:87G9C@>F9BB8EBDF9H<6@=HYX@kG1?53CG35;-()*#" $ '("2'6I,    + +  + + + + + + +       +  +      +    + + + + +  0 +6).- %   ")5 I*U6&D>7545%)#!%!!!$#+! 0)!'%*!1 %&''!&(%&*#! ($(+ '$""#) !,/ /3&.4/-0,%,  + "       + +   +(36;+,/"(%"! )$!&18&AD;6(6<-7E+.<'-6/6:#,7&!$'#)%0 -&,()!"/?84J1I*FD+'8 7('64-5 #':YZ5Bu*,0"0!3. ,%#2(74 ;-$.&'(!53,.#*C#):7-W&3$+!',+                !&")(,"32-78623&'"&.+73B;;6,13*'5."+"&(!#.&#.!'*,$(/#).""+###*!04*<22C&94$$)#&+#!++%5)))$)/+#*,&-'0'$*$$+*"0$",&#*,,--27=9PEKbQHMQHPM@9Q:6I86K0-D#!8)"4+'3),;"$+(*2/*-"!'&.2*CG'>A/-#87 02'10:3@D;B1(1''1-)/.',9*:13>..)*%071)4:?@G>D;R\'`\2TR5MQ1Z[%>5)&+;*3F7:8/01(00,90:;:68=/88+5,*,('-%1642D:EM:EP9EN::H:?F?CJ9BF/:>88@=BQ>NQ>AH7@K:BF95*8--L@;MJF:D88.49+2'%&"-),%*-1.+-!*,'-5& "    +  +  + +  +  + + +        +    +       +  +2 :&.-&  +  +   ",6K"K2\:*MH25=<$)%# % & #"$$(#)(%#%$%"")'./*.! % !$!$$& %%#!"(#!""%!!$ (#'*&'((+'"-"!  " ( "  +      +  + + &1"$$")$/-,&%06+(I*-*(7,+4/%&-,0'C* & !!2,*%:2)2J11@)(8#'2#12;<:W/3CB 8,*/'+))# '% #! " %&&)" &0*//3/%$'#$!((#F)#+;&<,--?28B8: )2&'*(!7+ -!$  $   !!'$&'  V!$4.2$  +        &6)@%)+"%$%,()#%-$  + !PW &"&!!0/?;B%J_$h]SS3U6*#53')/+#((#;&-%)1##       + +     + #!!$ %(1!14/:623+("& #*-)7,2++2,/ -''#"%#4*"#$+($#"$!' ! !'$&22/@(/-$%$!"##0#'$"2$((#(' )()!$%,!#'%% "%'%$*$*2-+<,3F9J<-L??R:>H'3>'5A'1I(-E)4M!7>'%%#*)2*(/!=;*AC(17$'#%$8%.)9**:'"4#*&6"%4)!.& /!!,#)!")%26)MA2A?(13)/.+*3%*11-535@'AJRM[rK[Eb†F`yFB[=7F+47,8/3-21'1+*60,644A:392+.1%**','--(8>6/=8?R=GT?FM7:D:3C>=G;=J;:?53;<2AC/FC2><7?;;@5D2+;(9A4FA9:524()2!"(##",$.8&5=$3LJ87=B%,'"%#%#&'%!&')",.#-- #,)$,.,5 18(4&,#'$' !%!" % '!!  E"%;' $' &,# '$ %             "#,, /$#"# * ,+&*! +=)!;I"BF' C %%'("&".:5>#:(&&(:':@.I#&>3.0'''!,) +:(&;9(8*95$$3!,$+0&!&'(,.0/71-8"3C7 CN!=>!051B!<3"E?'1?&G:*>96&8-10'./.,&2;1((*!(%#$)%-#$'" %&"('$$)" %#! (()/      #&/#B8>>4/")(.))*!##     .& I1&204Q!8N)D>2E6!'$"!/</770,5&")" '(%/&)  +       + + ! ($&$"!(!#,/6A.=B'11"++)1$(2*.,(74(*/ $!&(*"%& "!%'#  &$+1):-/5$7@13;'%(%&&# ' !"'&) -/ *2#-26D#?SdOA2*/">B%E7DK::\:Rg*Wh*3>/%5+*-'&:+-G/F4>IF#LV#CI'9B0+<7,5 (-&%!!!&"&' %"' & &&#!$&'476NR5HK.6<'72'0."*0,29/4615E,P^,M]&5?&26.5;06B.3=.6F2CO5DXDYgHAWOOkSa{SV~Qe…Dgc1>H/:A/13,42'55(073,69-41")$&-#3-&56.6<24F64B=>KACM7BH25@;8@73:5+53)31-/5*.;,.4(06013H;/fH0Y8:C24/)* ""! !$"#0*0,4>-1F.:J1=N5AP7 !      + + + + +      + +   +   +    +   + . 5%"/1)    " 69*@+!R/,U9/OG<0C<(*0& (#!-/'0=(368 ) +*"66'0>&%<'*)1' ", .4'3#  '&8&;#72041!*    +        %!& $%,&&,3,E.60)7+?27(A.5:" 4G=-R (,#/!-'%!"%$!#') +0%$,*!"""$2'#,'+'%0- &1",'' "!" &!! $$$( +.*&0&,:");8())(.4!2B/;4-Y37L/-K&*@5&"&." "#"(*4+!#7)!!!#!**)-$+   ")$1'()*.,*!""(%$        '&!0J'J('#"!1(>".463+  + +   + %""- " * 5/ $("&)(3),(0*%%-(;1**+,)*#,+ 1 8  +  +     +  + + + $&'=&'!#('/;0>4HS$6;"/&' ',($/9-3;!,3'($"'"" $!%()#00(5B.==0(.?(3+&"!$%-**/%("$'#(,)*2*#*!"'"):%HA!D(('$-+110;#:.)5',7/3F7Dg4ao(SV"=ACHIC<9@:)FJ5<\03B*75.-4-'3$'/(0-.,-+--/$'! ! " #" $ "'&""(0,?A09500&*1+%1#(2+*815E/4D7-@;&2.%1(&2*,70(3,+.#13*=C4DBInDQc>KQKRnGGXN/LVAi;>L46G0/;.261/83.202=1/2&%)#'-&*0-472+:%41$#$%!("%#'+)%5* "!&!-,/1%;!"#) " $)##1 /'""#'$'' "%#/0("8:1!%//-%"2$$'D!>6(-2%7%#( :599;5!80)$ !*.&$.)%      %@%"&+$#,( $ "      +            6,(+(#L/#       +  +  )",- &) #!5"$!*%$,4+90814RF7h ??D, (  "       +     ",#2F 5H.1BH(BG3>=;)8.51;495$/5,1/0,5 .+*&+"$!$$&+7;&NR/@W::B59?(72&%)$$! %"')! %$$&*$( $"#($'%<!(+&'&!*%"!% $! (%*246OQC\O>Q>(55(7<1G6B`.`m0K\03H+09.44,*)#&('#,%76$)1&&.$%*))1!-1%+'("$&2(, &#%""' %-!%%(.(00(&#%"-"(1%./&0-$*(!'%)()""1"%"*';/;09A9;R;=MF*>O(;5!,J#3K#75$86$12.1&22(32'10!.(#%%#%("*-(4.7C/>M;CO8@N=@N69B+48-54/47-.1+*4%+/)(-%$)%!'-96=bM`‘qegD`D+0*&*1+>?'EF(9>)6=+/:)(+&",-(3')3& !    + +  + +  +  +            ).!&, $  '0 4*5'!:,'W3.CE;7AC(,*$!#*(&%&30.4.; "@ /$ & '7)F"!;')-&'-+$  & ,6;).9# %  &!       + +     +  ) $#"$!#$ % %%(%"-6&(;./=16<.$+#%5-&"#('*,(&&9% %$.($#" %- $"#$#!##*".+%#'#2+'+5'=:!$ &)!$, $# "(!&*!'11+ '*$+"!)%$!+$"#!%!'!2&+#&"0>'.A1;=,.<+&$$3'6%(!#''# ) ,( /(*!+$# 8(!!!#!    +   +         +     +   1   +  +  +    + +    "     &+;")&$''%'*,8)!2C.>$.."9(3444B+    + ! "& "&  &.Bf#Cb793#G;&76;RT6FL4%,")/$0-!6)&.((**0*(!+&'0 )*+. :8+2B90:Q&:@ 183;24:1' (("!$ !!# &'$& "!*"* -Re^W[DA,""%(24B.9H+2@%*%2&5=;BOE]R,J0&7/(9,(,& % %&*#8(1;(#'%$%'!%%$"&%!+51 %)!'1!%&!! !#!""##!(!-%%!$(-"4/+(*%'/%)+)."(($$1/,,')'5>0GX24N6%@3,32&0,+('(..()*#''$& !*'*#((#+*,.#7,%4)#$#%#'1-:96JMM?AE2<@31:288-/0)(-()+&)* %&!##*,-EJKg|gw„aG_B1,"$!",(127A19A,2<-.8($)"#$#1!.6" &"&""&#$($     + + +          16$#.' '  ,,".",#4$$0*)66#%=!+$#"&"!#+(.$'+,+!2? <$ + *$!&.(8AI!(   &+!5),!!3 +                 ! )  !%)(0!-.)33%,;*3@")5+&1!151>OGAS*NSGMNQ?NDICG>B*)%(!..+#9#1'3*#  ,&/=$@%   (!(.&(($+"**/%%5#D/$ ,,%0&%+-3') #)"'6*(!" $(""* '4+1!!2!."! (" +"          + + + + + +    +    +    + +   +  + +  + +  + + + + +  !%"+D</D %;#2!) !'#!*)'   +    " "*B(K<97KO,Og3Jn50KR)79"%4&%/-&*(("'&*)74"+)&5+"1'23!@C1HJ9MD/-:01:.")%69- + &-.-'$:*.# &"%#$ " /%L<>/m;L|$KZ"Vg)dc-B1#& FE,DWD6S>&/$I7AM2#0,$)+#+%*1*04&%(!!-$**+*)!!#!%)&.279F/66$1+#,(+,.3.=:GZ?SV7EF7176'1.)/'&+&%*%"'$**"-)(71;%52.8#))';6'@3*;((>(3-(#,,+,04")+(+#*&0#/)!"       ! ##$"2%=3#/  '-#"$(#'3+%"  ##B58"+!   +  +  + + +      + +   +    + + + +     +    + +  +  2)# '!.%" #*4$1&9/       " ,/".49LGLMW6=J0I32;#LQ>Q$*2$$!#&(+(+'/&/2-/=#;>+PJBRUCDK8-5-,:'2("#&#'(''+%)%'%#(*&")+$-"  #"%%%%!!!"!*A!(I#/3#=./O;MW%@4IJep-Pv<4N,10',!(7&+?"*:>>31#.#, !+#/#+ "/%'!!  !!!&#",$(2+19/3;.AC.KL05C1NX7hc4RWIJh]`z?S^7BNC*72&-$.2#,1'*2/2?(5:",4%29$+4'0;&-1 ! ')0667;926065(76*:>1<@==I@=FB9FM@TBMP/63('))(++&)#!$# $$)#23+N96TIOZSW[MNLF197!39"BE#HI'CE$AM:1>E.++3799+9,)7'"+!)# !"%##+&*2037<2(721@C1LO"9A7H-$3.08"3976$88$!5(-2"#' "!!*&#"&  & '!## "$.*@9A-LDC4S<)@*'C)(6 !)$+,.!1<*A@*1>%8@63!$*% #%%!- %#$!! #&%)"*$""$ &(-6,=46>;7BDFY@FLE=LU>]ULaRQ_h_pcbpEEA932*26(4;&19*(:1*72'8(.:+*51+9-1@+/B)1%)*006589;:66;8GN-B@/:H:=I@>G=F*CQ+FU%>C%7D)BR*=J#AI%?P& "($$*!#!!*#" ##!!$ +              +    +      +   19)!3/&-   +"%.),@D*<+..%  $"!' *)1(600@(>'%0",(# 1#,   !)+!," #'$ !"  +   +                     +   0*/#0/%2"'"!$#)#!%!"%!!!($"($(/.  ! # !$.(4,>#3>19)& # "()'1*$89$=!+ **4=>"9-3% .#!!#"$& %!3&.#(!!!! +%##&,)2=$/%#,&#(&6 %.*1'1! !  +  -?7E::+)*#'!      !    +     + + +    +  +  + &    + +      + +  + + +  + + + + + +  &! &#    .&#"#2;?6"wW0T^/;N*6+#3,+)-'$/%()$'##$#)-%(-2)73=7)7B:,3:'#5"7 *)-.*9,3H*GN,%' "!#$+*!! )(6.'*$& !! ,16<.27-%:)9C@:5A/))!+183!22)-#/4%1).>43H//9-'2!$()*!$#&"()'$',*/,/" %&*"):%67+1I4FA>H;*OPEQO0NY@dbJlOI\5EN,]S8GF,MR,J?+08,!5-'4(,,"*+(7-.4$'2,3)0611>68@19C79L9@P8RP5QK<:F88CE@SHNS=AF14B07;?BIDJ]IBZC7E1%++&>A/?H)@G-)   $&&)    +   +  +   +             + + +     +"=<7#96(. !$*!-%+!?=-<181&,-&!#"   % (*)1)2#7"+1% 4&$))14 "" %! #.%*&  &3+$1!$"     +   +           +  + + +             !'""%!&0!,!$"""%#+/329<4?793,+.-!"   #&"$&## "$$2.%%< 8.C;MEGJ.L"3%*0#&5(!,./&"- $$!/ ?%8- ++$%1)%)%'(&01033='-25.*5!;6"-4&0"/! +   .$<5-30()%      +  +      +    +   +  +          +    +   +  + + + +   +       +  + + +  ! #   +      ")<:!+##)&-181!7^)8L,22*2#!*%')$.!%2 -6 $!$!%''H;&Q<1OC5066&-% *'$,#=-(,#.*+E)0>*-"#.'(" #"*( !!+=:36(&!,&%5&(2%.$4'8)0*'9-*C(>U-Ti4bw<2B(2.#-1&8M+>T!.>&2;$3>!1<5,8+2:(-2!!*$!$!!&"$$%*  !!-'$0%*6 ./$(!'&(/2+/00!,<&61$,5':F1G=1F"3T5LJIXBASNIeIRaGPhE^i3IU06$-&$-" )#+)(2&,4")7'*5,-;5)96.>03@C)CF@WJG\;FSF19C6SG8tPFjKAYA2:6'00-05/+9/0>)3@'6E)7B)8D,;K(7A#1?+  $"&#$#$#%#     +        +         +  +     + +& 7/:9!&65*/% #('$.#:!@*>-:/(00,(+,"#"    ! !!$!##"$)!'')$,*1&1/!%##"''0 + ( "   " #"8,C'    +   +        +  + + +     +      "&% "!'!   ,$24"0;&,@,*?%2= 3GAQ3K)2%& &## %!)* $'!1'), ''+/8!/I/'H8/?27=6E3! -*"7!!'%& '!"<& C.2$,&#"%" "$("'> -1&?*41,;"0C C-#'-!"!     *% *3 ?/;/-0/.'5"#  +   +   +   +  +  +  + +  +     +     + + + +    +  +     + + + + + + +  + + + &        &+1/83$;3>=,3//5,0/6-G?&9A&')#)"&& $'*(&'&#$&+ -1)*5>&@< B@#;,41&%1#"("",#7?-\jaR'e>/^A RPash†(Tw"$' "!""C30,&+:309("+%*1(26).2&04"**1&-,'(/*%42,B 0PBQ??R*7:"=@+/;;-C01>.3C/.F*+>(-=&8B$/=!(% *#( ' #* (/"%""#$)%"+))" )+#*")�+(8"$/!05(-.$(71&'/$)-7/8A3QD2LF@ZXH_QKcdOiMH[/2>*3'2%227'31*+1')2$+2&*8(.70;A+FH*GH:8NMJZHJUAL_ADYN=PDGO2>H1?P-;F)@J.=I47H79DA[QL…iLrSBRB7@<-AH-?A,99);8(64(7;+49&17A*J6,>0'5&')3*&,'!)"&"3,  ( $(!+0$*'/879*:.( +    +          +                 +  +   + +  + +  + +   + + +    + + +  +  + + +   +    +    +  + + +$.JC0Uf*Bw.PZ ;D(9K+,<93F/00 +3$''(39 *3-4*0 2:$'20 %8$8&)1&-0!+%&% #$)"79;R,TIDpJh‹Cz‚8r…B3;F4FJ9RMEXI@M).D#",(*%!41(7,+1"$.'4#*4(+=69E>IU;BX1HQ>=S?7PF@PA?OB5F@@M3>K0=K/>O+2B(:L0CI0CIEe^[€oWQX%*1$1< 6@!*6.5"!!% #&  + +   +   +  +           +" $%5(;1"/4-#-1(!" !%.*'#)!$*"-'),'6#$>#E)'42%2/+*+, #":D;$B,>.8913# .!(&*,4(&5%/'# ( &$  # ()-"'!!*%()#("1&*&, +       + +   +     +    +    +  +! +!$) $"!$& &&$))&-+&C=CI6F./)7/:((4')1!4%2".9%<'(361; +8#22.6)76/'&#$$!    )#%1*%;.<7 O@KW(-V)M:>J:/6W4)A2+B'!@) 3+8B#7G(.)3%47!OD5?&+   ='=!)(,)2+4:#$; %914114'       +      + +  +  +  + +  +       +        + + +   + +     +  +   + +   +  +    +     +   + 0.%;DE8B]47[->C7@41?5)6/7E45@&19'!)#*$$+,.4$$8 )1 !0)%1()!(#/" ($"*-4?CJ#=A/..A#,T,S6O9+:5*+.#)%-"(!$&"- #,&%)% )((#'#&3F,DN.=V);S)+6%'(!%'"*2&&."'/&)5''2"(5!)5,*&&-/)-(/ $(!%#!$ *!!!! "!%$.)"")*'$(,)-(-0((1*06(+5/(834C80C>?O=EM(=>67,( $,!.(#+#"- ,!)7+BO88I58E2>Q.=E.4E,->'7B,HZ.B\DLeTriK^Z5FE&./&).*69-EF+EF0=C.36""(*5%4?!4?";B&  !   +    +               + #$(5#@2%0:485!%%$$'+*+#*"*%/$-1$(.'/#H#G0 93.6.*1&( % $C >%4-<3 *>#&2+ 2')&!$'%!.'0'(3 %. )#  ! $  $  ("":"-%$("&(.+2$./!4 *)),$ &+        +  + +             +#&'0 *"-&"!#(>*3!/* &F0*;26$3>0*  06'&<>&9' &249Q?3,C)%%B-%A:#"G394, 6%4$7/, ) $-),&.#-&)'",((23-84629>..80%)116'$2%2&2 )3!"( ! &!(/# ,!"*+ #'*5+2'5637<64>+-:)$&%,#,;1:@OXYƒ’ƒ²‡x™wœK˜¬?hr9CH+24!73"5*_> C6#!%#"!  )&0.9!=J8V^8:K-,3+&B!"1 *# # ($#2%!-"%7$$.$ -!!)"#/$$+ %  !  $&!*, *("*+/4<:$7B(IN$1@%D&5JA>)%+&-%(-4+6.)BEDWT?cEZhIPUABO:?P4@N8>L28I16G34B18F)5<(04(-0+6>1BI;ZXSfbAPP-36%%"#(''1+3>7;L2GR-GB!6;78-8*6D&CT+"!     + + + +  +       + +  +        +# -&,//$#3$:5+A213),2$'0# ,((""*1+0%*.'6!"B&B3#/5+=+14,%*), +;! :*3.$/9',;0(8,2"&$!"8$06.1+0%0 $+) " !!" $ ,"&1&!,/&26,G+875-I'9"%%$(*"--, $      +       +        +"      !"&  %+%B0*))''&-#"1#,"&%! &),-..#.+, 23"*7,.3(4=&4D(2=$*,!.1 %9&8:5)C1$!    (!= =4/UR)SI8a"16/189D$% % *4!)R0#<6)6 Q ;*))%! ( 4(2P"@$7;9!/!1.$5>, /HA"?B1DF"MC/8##'+&$0,84'!* $"   +         +           +   +     +  + +    + + + + +  + + + + + + + + +  +       +     "" #.5.7@"+J+->56<.,5&28-'-76!35!:9#.2-/51#(),1,9%,!&'!,4"JZ(nu.NO*19$'&-$/5%**:BO{ŒƒjŠ—vœ‰‚¤—j‘š_‰au;{e#co)1T:;pH0g'#0  !"! +(<*<=%B(4:01AG2EY>QW6ND6H9?P2>J1-8,7>-:B/3;0/A20E->G(6;)/,1CB?{]K’hIgH0)%#"")'..*824E3FV'NN'MU&KP,LU/PU1  #    +     +                +%"*2"4) $&)#3/52 -72*6   + 3*,0'(.( **&0(2+"3$"=(;.'-.-0#*.&!'"!%#29+36#45'85,+<-&<)-+$)*)&C(?5<9*/7#+:""A +#!""+*%" /)!'*'489 .: /4.9.&/ &*1+(;-(*.%           + + +    +   (% !" !$%$ #"#!#%**486!%= 4)"& &,#(,*02&'4#6=!)C#$'.1&+0)+3$.$ "   +    $&<""4,-O)1D7/,#59$F $&&(##,"#%&# %#1.')#*"4!&*$0(64()7PC17A:,D)(:07=C$?*2#>&"8% %(! %               + +      +   +   +     + + +  +    +  +      + + + +  + + + + +  +  +    +  "$&*3*8A7'1< /"2 +''2%0:$&7'.>%9?$,=&.9$'8"$!$7 ,@').:4427<$1BP6RYIl.;U&FO>L!FK!CL#ihHedj]j\_‰jk’}BxV:oW1Yo)WU(EA!-A#[): $'  ##' -(")#5@),/.&'-!*&+&*%-#,#-&.&- '!% ( , !+$$ /)1') %!  "*%!!# !("5$)1"" *(SR3CP/JS)93*B;9576+.<'-2*5"(6*/<&9;,3*")A.KP2CK)@N*5A/1<>3DG+=6:B9;J5AP-@=+-6)+9).;():,)75+>8&5,-,4ECKg_”qU]B,(  !" %&&(,-6=44=5>I1AW2=Y:Gb5FV4!! +       +       !  !+% .0" :2*>-"76.$3/'!(!'"-$ 3./+*3%/0'),!)(-'<&:';* ;.#5+'.%%-% *( :?'4-!71(2;(-=.33,%5!)/!2-968?&FC.+P*C%#()&#  !",(     !"! ""!'*.,.!:#.$&+'6"56#'>%+7!*0);'533 )@(.(4$      + +  + +  + + +   +     + $  $  / &-,( 1:,  &!"&)0-=$ 9('&&'!)$$+#!&#&&1)"--% ( ( ! +   +    "6/ 3Q D&1%#"-%0%(3+!$'72  8$'82>(S2!+i*"?&$+&P&"}R _M25?8)3$&(.#2!2%#"*$     +         +       +    + +        + +  +     + + + + + + + +    +    +   !4)2() ,0.1(,&/'$.*'#+)'8)!(*!(&$%")*3%-##*+''#<-(=$+@'8Q.6A:7JC7O4-=8!65!95"1<'FQ=TGahDtvROdJQL469612<:37,(-!'# >,8,5/!50&(!#2'-'.(3(+#*@/0D#(8 ")'2&!-# ( ')!))!#%$&)*$$/ !'$#"''%$*)HNHHVO=nj<]]BX\6\S5?P0@J%&2$(1!(4"0? 09(#8"*8#(*4-C@5L35?-:C/;A-(/3!.06K:6B4.D;AN%'1+",% +!%. +- *,#*'(.2MASgnœlJ\@%-$&455514%20*0?-;F3=J1?L2;K8=G52H/ !       +       &$)0&6!.& 9*;6-*A.+,*/'8,>6I9?5 65)31*:1 (5 9* A(?-%>+&6-#6+&**!)"(##&B9+60'3;*:-,0$+% 1(%+(& *-'03-3=,!D251"" #(&    "%#'" "*#++-!/(%' &2,7(+5!-7)/!'4.;#.5 /(          +  + + +   + +             +#,&)+*%*0,=;$" !$&%$-&05!<-*$0,%0*.*"1' ""0 &$#"!$*&"0    +      '8B!*G-%1$* ('+'!#')!*"   5)-K+)(37!?# 4!%s.Cs+!-"f-ŠfV[XS097  ' ' 0'(1(!"/     +  + +       +  +    + + + + + +  + + +        +          +        ( '.$165=-/&*-#09 0&0- $'"*(0.7-&%& &0("76&1/0447C1DG)28 )+'+ F?:G\C7QM:H?4JFPn<\_0\h*Yz/]hK==@#<_7fƒ)jw,NL+4$, .)"2.0"*%!'#'"&")-",(%#"%)+"%""&%!%")!#& !!#*($  $$')"& !$)'!!%4!5A4H1UbV€[]|KevRd{:IP@5C);;& /'.=*2:%*7$4:+25!(#& +7 07-?2?R<]],VI&3-/25'1E*"H8!J@%F:,BC-)?,"/(%&& )'2!#@&3.$B)'='%:+#1)$-%%"(6 2+/.+&0)(&&($$(,)!&*)*--"',(")++3%!!     +   ! %'*'$*'!%!)%($2+),#&+"# "&$      +    +  + +     + +   + +       ""4*4969$(7"!&!#&)$./31,?/@4%# 27 $#**%$%%1+(=*>&6"7-"  + +  9&&(%  -##2'!"%!*#"+#;%3$"#&*`D&Ek \,#‚mnb`]9=6 + #)5&    +  +    +  + +  +  + +          + +  +      +    +  +      !! +,+., +'#))$%,0")4)$//-1"10-4#5'0"*'%-:H&;AAB.A5N$5O!&;$1!')#*.*;H%Y[7[_3LR FC;B!Yf=WXG3F9/:2.F78HS8NH1HN/9N3=I(G:*I07FS/Ec?cVHn3Xi_X:6&%-(#!,&"% #) -@%=H3B.5&+% $&' &&+$)(/(+$&$( "!! !&(%!##%#% ## "$!,0O)d4^.Ug-FLCN19=+88&!*.5D-69(2<'4>"35089;A<%,-A(AU=dSLi6LY3WfGXsKSdHSg:PY&46&( "%%* #''027YBVdSi@HT;;.($ *'8<(CO(FL'?I'>C,38-15)$/$)%)-   ! $ $%!#       +  +! +#! !(2&4340,5.0<..J2[<"eE-:K0!85-- )#&"7"9&4- 9$'A+;/%60#+,"%"!%/)9/=3&?< 3>&:!(-. (+',#'* -%$%    +    #,&#, .!)!1&!)1 ' %#  + +   + + + + +  +       ' -%  !#%().0'&6 %6%&,).'*.)#*+$#*%* %#$)$*)-!($!)+$)"%-2'5G=# "1"*    )&,&/$ & "-0$*:)#7k=*=Ak`\`>K4)   + &"#')4+,($       +   + +     + + +  +  +      +        +       % !   %+!,14? '< $6%*%*4"6B)87)).*'%%''&./,"!( )>0=S.5G$%2%+3-!0%"$(-%%/ #/+9B7>ZNIwMUw?Ha2'H=,YW0b= =-)5(%//)65AG23=2$4*+5,;D3:7F$%6,/+2#)#'$ !,( /"(""$&""$%%  +"7%+F$/;8<3/:7BS (,%((5-073$614E0:H%14.0G5;O(1<+./F5=V>LF4F?;SONl]arHDRE172(, .*)+'+!62*+%648]JNrQIF,:%('/1(@D)HU*C!&3!'C0/P,?J';?'49)3B*5>)3:'4C,6G'  #    + + +  " !   !#" '$&%(2!%.&(71(A4'F4)FA0=B<%9<#,)"43',)8#5$2& 6)#/''%$!$!$&&.)"8"%84"1=(,.('')")(0$2+     (!$"&"   +  + +  + +    +   # (*+/0    +#(+/!#!%+$"- +)7<<5;$>)  -*$9-((2 *!.""%)#6+4"#! -+" $"$% % &!        + + +  + ! !! 71('.&$&%(',/%6A(     + *3I@Tl@RE113(+/ &     + &  +     +        +  +        + +      +      +   ! + +   "#")  %)$3;/948 0-,";3**2*21".1$-/$+!%+$)1+$)(,0+9A''3&)6+&0!"""'&0>,0>$-@##!$,,.*7".7'%5.9C)$8$02*&.0&9`,KM.N08O18J09[:ATK0H?"9/+;!<>-1&#%**0!!%&10"2-=2 *#/"!!!$!##  &%+ "!1.%5<);95/@.#(%#&',,++;0EVC=XP;N-<<$7<25EAL]3OI87AV:ZMMfBYi:`\>4K0/3!&*+)//398ZJKƒa\€cB\:$1%.)54*AO&6L&1;&,<%-;%'+'"'$!/#%*'#)).%       #"   +  +! &!!#("  $..('# &$(.#//4/(>9#>=+==*:75)31")#&55(2&"7&7'0*#-$!2$/")#!%$ %(%)*(-+%0*#3'3&,-(+-.*21)       +  ! ('%(   + +    +  +        +  #!"%!+" /%*)!.%"!!","(#!,"B"(5**6%+8(-&/0:?!*A+30! &!""     !1+ -! 6*>=!76 ( $'&"# *2% + %"     $')&?B3FO90*4 + +          +  +      +  +     +    !   +         ($ !(3(:02>+.1 ,/'(70&0(2G&26*)7#*:#1!),&(,.3A)(<,.%*&.-&,*%+,)'$&&$4*$/%" )""-!+&,$!*#%#(5*HJ 2="#.&,5"/5)-('&3"7!+!&, 91*  !##$(#'-817754/B974+07#11$)02,1-'97-;?>?JF:9M8<2=6+'1+ )? 3F/H:,:N6QKAPGOW;OL76A4=?864;/6D:DLDXQA\F58<==J;R[+cZ%A6"$,./7@[Ka|cdqRHeD1EB*AL.+*?%'</%>55:<8! *0) D3 .8:6 @90 $        !!(!)))(=&!  '"!       +   +   +     + + +    +   +   +  +  +    L:8nO <' K\ UXxœ!s‚'j^vxFP +   "!!  + +  + + +  !"%*?3.6+9K/AD-?E-%6.'3-)>. 3)%0*&3%"4+*"+7&,$%'("26/=.:N03N(-M12W.%2 ' -'#)# .'%3$'4+;'/$)];KY;GH;=Q$'*"1(-.0 /7 %2(.!LPGDGD%-."0-)%8@"($.+/25D:'`Z*`J+>ABS&))(81GdQaŒ`]cOIcL6dR-MC)29'++$#!$"#%         %(    ""$&)+/$%+!%$"  ) # +#"' %" #"#$  ()+!*.$*0)+,%-0 &1'%/'0-'/-$#0%"&('"%( ("%&$$)## ( )%'%! "         +     $"        +  +  + +    +     " '%("$%,'/.,(1%%,-*5%#2(3@(0*!$&-'9 78/7!-/!#($&5**;APB -S$%8+/+-1<-#0+.1.'%2!',$ $ )   )  +   ,/#H,"U,&-( &.*$.-!,*&$#$/.*\)&1%"5%-,#   6 +/ +   '! &-. 0(& 1&.! &  +  + + +  + +   +    + +    +  +      + +     + * 82Y@x13EP$PJSq%8M64-.15+1+1!.<*,@5Kl(BP0@T:?P&ME&MQ;8++FI+V`@G]<\„9FXHNc\Wt;ncJ`hMjpXLbdYuJ;QQJ^J?VJbf[J_B2@*!#! "#!,/&.C%6),05-9 (/H,$%3 (/'"6''/: ",0''5 " "!" 4"*(2+7:- +       +      +  +  +   +  +      + + +    +   +   +   +  ";-C($0><DT3     + + +        !#00")4$,/1 &'$*%+8&5$*4"6LA659*5 &+%%#!"#%'&+-3!2-+;A+OJ>:*0@*2;.+3%-(& -#%(&5<1Ja?';3&54$14-; *9-.') '#$-"+6 "''3#4+8G!FL.= 77.2&>H3bf8Na-ci-Ya->[/]k1tˆ!CL'/M3=\(*9+%.2*=7:D25HENqAd‰6`u>4;3& B1&T9'*6)M*?^5H`F[_Ph[QaWBQZpwEfaB:RGK\S:PS9C?'"" !*%/:%(1//;04B3=D./4",2#41-.&1+(1..1.+=80F=W€kl²xMeI?P:@B1.("'%'%#" #- !+ !)"*       "  "  $ %+-"  , &$,$&# (* ""$1#/518&.7))5*-.!*/#-,/.0&7#=%9+7,:(B)/,-##""  #% $)        +  +    +      6 );   -0C8;4E#5<^8IM9F,9 +)%,(# + # #&-),3(5"9#' -%)) "!' !(++$"-#*% )-*30!H?$=L":# " #%$/42"!##*&"'5%$())&&-#! )%/'&2&)#)  "! ! + 8?-P N19 1 # 4 ++8 $6 5; Z$41#HF+G(#7&,/")%"556G':B#"#!0!1&"   +  + +   +     +  + +            +  + +   +*,   +  +   +  + +  +  #&(%!+$!".(8#.9@76:!6:(?@%#06'8.C>+8@')/$&+%%$$*-'16+:G2[m5Fe-CX.P](`w 0>27CF=6#)!+449V9>E!36##,.1 .4""3/3") )03 !&&83 +-):?3XX/ISFKZIKa:KE(5-*!-'$ #"##-$)5$*4,0>81A+5@$28%59*97+44)91+9..764E@]rf|šyV[A;Y>2<)"!".,-&%"        !     +    "!!!!*+'!   / %%'$+!%"'."3-" "&'&,&,#+1((1&(,"&2",+#7*D7N= F<77&,..)"%$!!"$"#&'!  + !&$%$)" $#.! !                +    " ! '!#)"* 3,4<IK$Ab5>Q6JX+hnL1dEE9**%$3#- ! '/)B4<@$-)+ &! 2%-H(*# $#$ 3   +   +     +           +       + +      %    +   . ()=K;6Q> )  +    +     +    #*-B269#>D'DP<5 )$,*-*<<'2-&2$$0' )&' 1/.+3:3GL8@:0=;AR=Kk<5Z 47E(4(!1@$DK"$+#*!/F1;('!!*(&0;$DX(=I$7E;7^5(H36HD-G1.7,3:)$%%.+4B;K:.;F6O@F\4Dc1)=,'?3"18&6;+?B2B/897yqUr‚Kz‡I~˜7rw,MO>JC/,4485=NKJ_Ka^UMbXDdYHfdYxw_sW`b>@ED/HFMr:fl$OC#GCB@HH822149"5A$?G.BG+@F/=>*98297116.84*=4-:2;THe‘rz›uVmD:b?2-##&/-*           + +   +   "#*%""%$  +% 1 ($, ,#/)6#4)4/1/%+#*##'$(*!'+#!-$((#&+!,++2%42)95/20,+)3'!#"!# # !)(!#%$##!"'&"!        !     +    +  "" )>%'FA)(X=68I'87+J,.g09#.400 A$))*) -).$& +! 5E="0O*:,) $-(8/*#"%),) 2$"%&/&)  !(%)#&$+&7-&2! 6!*#-.#   " !&*%#   '%%!'&    A%Gi*KX1>>>;@A2I;KUEN(%72//!*.#$, 1/"!(&#*'%$ '22;,J (71#)&%9"2@",,2 IN-RZ-WT+JR,"0/:=([Z.EF"%,%.3(*"&%$6.#4%*933?50<2?J 38.0)42;&5<(63G/W`3i{5mw:Zl>FN<@P4DN?KcQhXg{Sdl?M_4BH0>L:GWPY_UX\D@L@Tf>?KQ6Je/RkLfPRW617: 6Y@ZSbtEov8=K46H5=P+KO(=?'9>):F4BN7?M8BF+7=.,0-.-)+).4:,<:=p[d¡€x«vU‹W;a:-#!#          + +  +     ""&$'''! #$ ("   ) %%-$3*+*#/(.2$0'*))#)&&#"%$+)!*&!$"#%!%#&*$,*$4+&5*'2"%D"".# ' +&+4+%%#%               +  + + +  + + +"5 , >(8\!3O9%7=*+)/B-8>3 7<("-0>@.2]+JKLBP0/O#;;/=A"6H 7    +0% 4%*%2%*#.:"6."('!*1=!%(4A7!;#,(&0.02%'($,#0$C$(9+-7''&4&.-102 #.!/1 )45) !&!      + + +&'   #/   !+  3&< "# ##!9?/>=AI;!D->?#3/"-/2#,5 *'4 8#)'%)%% . .   + +     +     +     + + +   + +  +  + + +     +  +    ! +  !     +   #"   (#$)#'2;<NW>?*168/0(!/4GZ,Pn37N37B:@UD67>),1&+(&6/,/,356Nfdv¨‚‚›vb`D?3 ""+/,&     +     +  "#$! ( # +))'()'()(,#."'*(/(%'- %$#  & $%+$/%7"7( :&(3#(( % )35!5$!%     +              ! $ +"" '#( "(4)<+(%*#$3+51.-$G<(B%3+".D$84-?@$BB.C3"@1)?5+",(, *$. *0.9$3*#0!0-""#&9 66>+0O&=8MN%Wd*AY&5M",E!2< 3@.5.;B71\ $9+0.?3-='*7,0!#-'$  *$!") )$    +  +  + + +      +   +   +  ;'+G@- .W "#=( 5J(:$-;0F9-0!A*5'$3H$/P>G"H%-'/!!))  (' )'$#    +         +  + + + +  +         + +  +            +  +  + #2      # #$!&!&&+./$/90VZ6dq+a^!I^"(HM3K7= 99, 1#' /+40Yd)=G82$(,3[h6Eb0QaJf}:N])TZFar@V}=Sn?=[65L82EJ:Q/!+1NvCXr%(3$ +$pqEhx8;Q9OvM\vCJ`=JU0Oa2R$-B#*8;Aa90?*7A!'5"&-"!*)%1&-8(,3#.4(18%67'4809@;2DB1KA/DG2SECT6=EA7SLPdQ^sOuXq{Uk‚KJ]T@[QJfHYjJ]jRNkZYzFS\:IV5IY1MR"2.3/7?39BISSK[`YsO`rImwLZiC6<@3CFJWD8E4012<32K>7MH0UB+M7+GBGuYdwYdC>EQ8)&"%$/.&=@'A<6- -.,24=9C99%"  ! +   + +   !    "!# $   -(&(((!&!''",0- *7#&3 &)-".8'8 3 %4$;&/' 5(#J%!N496%9)'-%#    #   #!" +!%      +           !   #$% "$('1($!+#.-)(  &1,!#2(/%'2-+9-0039"'$# . #,)&-1$"6*2?373EC!.*)>-/3& #* ) -*,"% +$,/&.4A100+87%'%"#*!4(,7$'<1: 2<,C.? '5..# %&&("%).""73++#".  +  +  +  +    +  + +  +   + &O',((1 "4"$&# *$ #. ! "%11%$2!1:'1#     +   #   +  + +  +   +  +  + + + + + + +     +  +       + +    +  + + + + +   +    + ';-K9 0        %!#2#)%$#*1*-*:/707#',&)-+@>$CW1>V.9H70F5 80(<<*MC-JLQo;Ml6IeAHc=DU(HG&B:#JQ,FS/R^(WY?•µB‰¦Fr“9H[$MH"LZ$NV-.3:4E8DD6CJE>S:foCf†I9a=_K`’NLa@=Y@]k)_b)my+OT(!%"6B@$>4%- '*Id\Cv=2R2-)+#&# &"#,,<%);+= !/,3A*09&1%$1-.#,'+##%#!&%*")$"1(%6+$51+>+:@'9;+$.'%2-4G1BU'CP:ZtXz_r›ahŒW[}QJ]97IENXKNjOcvMYeUK\YMbE9RKH^Hri2ea(fd2TM>NYAZeOBYV=KX=Z]J_<7G07:@4B:67.:71GC5BC>AB=FD3?B?BAP|aZsQ=>(2)+!)09A!EK%CH)>D&DA#>A+.#)$,!1B@D>?=A<7   +         !        !"$'(%"#*"/)$#+/")$')))5#)+'(& (&40 ."$.!-&&)'0,"'/%" "'&&) ,&  + +  + +       + +  %" !  ) )""%!%!!#2C(4B)#3,.&( %(,+$2)0),#/4)-3&,C7'8,#$F&!**($-  $3!2!,)"(+. 332@&9"9,#)5!80#1D5B-;<7)58!(.5!!'$+!"%'% !#-'('             "/  + +)! #   (' #!" " +   +                   +   +  + + +      + + +           +      + +  + +   +2$=2D<_6   "# $!'!')%(*)#.'(0+*FH#3O.%?7-=4&>,"2!"+*!.%$+/.@Ih’Eiy<^x:]†9Uu<‹°;„¤8Mi4pŠ<¾ÈPoˆˆv lKuY8L1QZ7Ta>Qg2Q_'M^)Y8Y6g€6RuR;[G)A:4F`U~OTv;k…Ak…C`yIS|KCg.%5'+&4@ (%/@BMX>P]-[Z+QR3:A0;?+;E1?< .3*+")+6,6",%!+)%'(0"/D "8!'! !!$!'$,)-(.60BQ/0@ $"(:A5K[6Sa=;V\>[hCeY;ZQ6[JRq9?J5?QHB[[Wf]ShNIYH:UEFV;>->;45773::33534887>SGXa[„U1L1#)#''0$6D,9M.AL*-9*1;';>>? 99#8:&9I)9G-9R/HW+ +    #" #" !#"&   &! !#"'05!)""*#%"$+&-%1$)& ,'."<5)7""+"&2">$":+)    %#$+%'   +    +     +     ! 0!-+/#'%&#$(&,+3,?6+B(7?4FB!-%%*)    &*$',!.,!.$$"*5.8%,9"*$#(!'/!4)($!%"23&&<#%)*##2##%%*1/4'-:$/&'$'$-',"$9/"%! "   !%&,    + +     + + +  +   +    +    !!   " !    !   +   + + +  + +     +   + + + + + +  + +    +         + + + + + + +  + + +        +.*,<"#"!   #."/0" $&"+7&- "23)*%%#26#,0-+"-$*''+10>Oq\~ER‚6x¢>YzMw’–{¬tq™A€¨o Ô˜M|Y\j_^vE?_0XuAnƒBt†@[nACV6[u3NiOmtWHX;9A.LJ`n2b;Mp8c†L[pPBgL:FCA52G:,%36&'2>PI\xPWwOZoS@‚–Aq}@PS>:G>+9<&51->@8VGfu;ov41@B;ONGZKEV5;>?;T<@NA2GPQoZo†am{Y[lD]nAck2WS09?60=*-1+0=7:C7@M?VV0KF5jP+9.((%-&)7?C^whg€a6I2!!").)5=+4=$09#,5$7:(7F%:F%:B)2@%3>-6E2DW: +       &$!) !"!!''&!-. ,)/$   , #%#"+#*#&)#,&"#!&%''(#02""'%I?*?.%W&"B+2"*!)!'" #%    "&(     + +     +  + +  '$#$-$3*(")/( / *)"),,/8 *?+8260(@-6=)614?5#06B+*2#%$% &* +&!)*)'6&;,'52;C$3H#):)"$+*' -(  $ /+".((3*$(1*C1#$+&*7%2*'(" %&&&0%#.506,5 ' ! ""#!!'#   $$+% $!  #         '       "     %    + +   +    +     +   + + + + +   + +  +      + +   +    +  +  + + +  +  +  B= YO:#  +  + +70K;ESR>5"  +  !"%!'#.0"0&&&'3:$:L"=E35=Hiv_]:8;>71MJ=L9DRRz‘RW£aW`Ÿ¡JW‚ƒ`t‚[pBl}HGhD9A1DMR`†X\{\i…>Ž3|„0JZH„•Z“5n†'Ut36pI+NL+5=GPT-C;-.-131LU-MP%" +-7$>WDGi[=TZ=_M8P9K\9?S78O5?O(7?.9.7B(/9'.9#(0#*3(0$(%#" $ #&&!0?!7>#>@.5@2+=*0@37()!-;ZH{h}«QcŠ5CR)74",2",0)@OH_|RXw>AM,BP9@F@2F48M1N[?AS--@=S&D@%4;7SH,:> 59*4F6@D'% #!!-8F60A5,>49P(?F.+:.1A,0%$&.)!-    "*!16(-!$(939T8GV4DK.FJ/7D1I^!LUNU8EQW>Uh@[C0K/K^$IQ#?D+2JB:_ZX~>]m7Tq;gw5@M13A5/B;2I.4D)DQJj‘V†™Y’®VޤZm…\n…%8?*8@+2;*/<*,5+(8"17+5C9RkD   +    "$#-$# +$ %/).2"! '!-#'-#+  +  !  #'  '%) +* +%("&("2;#S!(a* q=)UI00:5##:*(%#  + "  $!#$#("'"$     +   +  +   +   +         "'/%65=6):$00$01!&(%)1.#,3")2'"!<0,4%-$$5*,.8!;I&/# )+)"($#$ ',#1'$9(03$%353<-;6!(#  /%6+  !#*-)* $1/$!;(<3!7, *! 4"(6".30.!# #& . *1$&!!"/ +#2 +% +&$)"   +  +   +   + + +    +       +      +         + +  + +    +         + +  +  +     + +        J8 tyG=&O6&Q.2.+:/,8-3!3 " '!"%#!"!&     + + &15)8-1"*5)MT$HX2; )4)$'#0*.AUiFMaB.HKAYV`wIu\‰µZ¥ÌUtwge•^bzB?MtPiTo‰>žœC~™]Drn=}`]Œ`aFcwJ^‚<\jX_c;sb(i\:WcFgœ;;Z+,4!A>1\j20S.0@1BV1Sm&7K,Lb,JF&,6!$7)3@)4@-EX3GX5EU?CR.9K'>F.:D08D41:&1**# $!! ##" $!38$48)*&.&3>@UGIW:HP3GI/:F5JX@Yk6P_6?N<6F.)641A@U`/7I'/3%7D+JIFkIUuKZs?Qj+BK0LX-TV&>T/dvHz‹Z’¸gŸÄj—¸`”­T¤U¥Ç\±Ôb ¹g’·\– Xƒ—]KdNDN>22013"<1#A4/QAKtXJiH.62*/)--8%;4"9:)AK,-6%+316@*=A)9<&++"!#!*736K+R!'W,f:-KC5!15##7")  +  *# 1'+6!:-)$%   +     +        +   +   +    !# $* 5/42!':++3!'4%2+&4-193<&%82'!+,7'8!(7'!-E.CW!PS',V =<GAN?P# ?$&%#!! "  )/#0! 3-@C&T4$1*$)A%( !$( %%.&2  %# -  " +,& !'$!   +   + +  +  + +  +  +  + + + +  +  +    +  + +   + +      +       +  + + + + + +  + +     +    + +       + + + + + + + + +  + 9]@EbtBYHANE^n>0V-Q2'#*'( ! '(   $-)#%+$.-.(! +%#-* " !* (1-8=@(UlBBX9&?$%3*'6IH1X7"+'=GOY;DK'+B:6"#&$*)6'%12,<7"5@%@A#9,+)05$;3*05'"!"  #*%!'%#")8)5=(7A***1,N55KE8ZAI^46E)5B$5;**5<0H;-;!$!"+1,=AKb(7D ")%-3+<#."#"$&"%* " %#!"%$/%)"(((,!3(/:/8"(02):8'2?-A7=A72<316C6K::L,BO*3?$(0, ,/(5 '*&'040<&0@7CWERmIb…FUmB;\LQuKgapœ[Œ–TerREiVPzUOkNJn`w¥fx›f³w Çr¥ÅQœ­F‡—B Ÿ0fZ,XJ5J>AeW\…`TpP->/!75";A5LJ-<8)>F2>@*/3((*!"!()'.('..2#49-4B5+>?3B'4K)37 %(-=,@R&ES2A\.()92(81"0#&.',-+ !-&    +   +    +         ' '+'# #*)5'4) (53/%:(%2%5%3/ )=)&/+#/+!,.+E7>()',-8*77&"%)740:959,/@(0C&+8)4+2 *       $$ !**(4)F15HEC- ,!+""       + + +!     + +  +  +  + + + + +    +    +  +      +  + + + + +  +     +  +  +     +     +  + + +    +   +      +   +    +   +      *1K9ybZ›Ge…3r!Ez Jehn(†$meˆƒ`u8(##!$-'&&'-$'/, "("$$&-*B "2)2+AJ129#!*&%1<F:#\T>N_0IG*UV5lkXo „o–qd‹iyOP[39;(;HVH;\jRt]Hi?CM3GeZQa_UfWC^BadQJ_@"?<&.=%57+",'"%0!!+"#    '!$!,114'3=,7<$2< /5%.6'07-5F7DT3]i3`f6S[4C[2@M$658?!8C-COCE6A!6O%BV,PZ9JfIOiHH\5GR6D[MHgR\~YnŽOZ|:I[9N^8Vm5czHe€Yh“Ylšq‘Áw•¿hÑeŸÁe¥Ë[¤¿A£¢BŠN{g]z_FD;3+*$5>.RL2CI3CE+IG3><''%! "%)* 21#%)'7H3MU3>K5:D:  +  %  !    %-'! $      ?W%i+i8%[4.J8'L12M,)H8 791$&).<:4J99N<7ID>JB7J:?=17B)1G/:2*494A(Q(- *#!"  +     +  +     +      $ 1)(;$%#!"!&."8",+D-=T+F6&."/#- (2$4%* 0*,*"0 54!(+#)*&0"2%"3##-& &$$ ,"-5/   + + %%/&-K/K"<2,"4!") $%'?$A   # +         + + + +  +  + +   + + + +     +    +  +  +          + + +    + +           +   + + +        +        +   #'YY†d eT!BM/PJ`fP;UDqlA7;e`}‰ma—‚¨c‹©0'] ')3*#$$&""$(%#%-/%.(&!(":C56G6B37B:=T&0P4*HI@H<>Q3uBx|TLZkPsZ\„Vb‰bJv5,E,.C46@/%=3M$ .&3/%(F>6L;6I<,H\8>N80AK&5,>B#BOA:I<3J<5L9#B=)3*<8)0! &#!%'& " #!$$.*,=?,HT0GT-CJ*-3&/3!)8'6F,>H67LME][VxNi{8VW.FY-CX)@R+1C02A/=Q*=J,AP,HW4Ob5QgCZrC^v7Rh4N]Ke6La?Rb\V&G;*NK:mp>dj1HJ4>G236%A=56G=!02'./$ ',.AK>WCDZ3>V;       ! $"!    '+!%+ %!""        G\#k0l9'[:)H9);+)D+!D:-;99,/-8%6A I7 0<44(/76?4A?*9R)/<$%6",*!!  '"" $//$#*%*"=+""'$ % + +  B1* G1#,!(#+.(7 #$ ,) 22/        +      +            + + +  +                +  " !     +    +  +   + + +      +   + +  + +   + + +G(N+^3cA9VrFsZ„m &‘8H’NL9XnhEDZ[‚'F„. B#$"%' $/. 4"("*(%+6:>M.IP-AK*9B%Ta*/?,03&76%ON0)?98_gReNCm;4R9;SFGSQ8M59<" )&":0-*&G=%5@XLEN'AR(0F0;K-DY97G2*802&#-'6P5Ec,2>*$)%+%"''+A%#' $#&- #,&!"   # ),(+"68"#,*0=839E7<2B3=D!8A'GN3[^8Ua2HL74@O.HW7TUPk5UW2AP3DT.=H(6A+4D.6L-L\2ET;A];@WAAYEOaBF`;CZ9BQ32D82GB8E?I^J\hEZfG]eKJbCD^>ASBJbNbbn—fr’dU‚]r›y™Ä|›Æq—ºi›K?“ž:•’D|M€8WU38<+>F0ac0fi5‡€,HF(6E$>:'*0=2@>>N72D; +  +  + !)!"&&  ) '",&.&%0#-"%!  +  +    +  )"0 .$%2"FM(c.$n:(P8+72,2#'A#"?5.645).)"(!5!05 +2 "(7"06 7=$BL59Q3:J6(H=';2#7.)(-'4-2$$*&.#+"#" +    +    +    + +    +  #'2#5;0<%:8**A';#,6"3>#-D 1/)6418%6D$7E-1C(%4%*)"    + !%!&!"$&  &)    +! ' +  1$ +( #'* "!$&+"! 2)'#$                     +   + +    +    +  +  + + +   +      +    + + $$/ *$        +   + +  + + +   +  +   +  + + +   +  +  +A&‹‘ >m{.874%3?!6;9Q9Ij9Lg4Be=zR-“š3SpSKViSNhE7`HD%1K$5O$$<))b+-K!(( ! ., +)" ! +-!+'",&$-0$0.,KS.:L09<2dk;Uk!(7-2)-;0# ',>XN>2G5&3&;:.6J5.8/ ,' $!/(?1Sp-/6/?!.#!#.'!(  +      $"$5'9E*CL%$&!+ +(1&202H3CRD>SMAVFXf0AE'/4.+:AO\Jhs3Zg7bl3IW(=M&;J&@O+;J7M`7]`3NN8AO<:H;6K6:I81D+16!".,1@3KWIToRauDTbCH]!0;&1@';?!=H$6H*2A&B)'%%'  +      +  ' +$ *1#-&,3)%9*   " '%!!)" ! $&*-+$ !)$4'(5$'#(+!!   + +     +        ! + & + +  + +    + +  +  +   + +  + + + + + +  +    +   + + +   +     $$ +  + + +          +  +  +      +  +  +     /‰?’*j51/A$cV ds4X^A5>'AU82Sh+Uˆ2gP'sB(D5+>W,DQ+!")#$&!)&'4$'"%'/'*--*6 -,"(%/+3-<&/#;80RU/`n1PgLIc3@L"#0!)'3A*K'.;2$ 6+-E&CTEDDACH2;HYK[JLbC?_5&8*ED+,F=2R57VCNZ<:<<?K18 "    +  ((*&!&*-377I5CH30"% /71?X?Ur8qy/Z\,FQ/GO.4@'*6'A=YhIObL@TKA[BHeI‚–G ¬B¢¯H•—OyŒKn‚9Yl@W~]t£uz¬wаs‰²g†¦^®c–°s“½iš·Z‚¤\œ¾O ªQ›a‘¯]€œHu‡5{y>xC‰–@‡”Ew†J*>M*0N. :,(,*00'%4%.0   + + +  +-+0 +714DB!!$0(4.5%5#($  $ ))!   $(")'1$!!*&+-  %"&'!!!& ,!'! $  + + +    +   +           +    + +  +   +  + + +  +     + + +    + + #    + + + + + +   +      +    + + + + + + + + +             !"Q#W#E$+,0:5"3),3)):(/:*A*#2*+1)%&* ).! ")'%&%  -)0>%#;"2(-<>7K);!4'$/,%/<DXjFTdCM^:I]10B'  $8,#<5508B(Z]:#=;#E8)66*2@@E/M6AK(HN975KI BD-5,7?DOf2Z{4Hv1+7#"'-)[J>5QC      %"3,1C?B8A12E8%<6@G%DW@9)&=>(EL2=I>?RBDS??RQUnYE\AE`?Yg:N^>& 2*H''E/"G+$70!,'+&=,."!+90 $%54"2@8'>611%*",,!(/)+ 5(')(+ $1 $. 2 * +  +  +    +    +  +    #&!'),$)0 &1$,7%-E01C-7A44E/4?+"=+"'' ! , &%#  %% 05'.$457$&   +   ',')'1(% )%  %& 1/%#'#"#% .#)!, ("/!   "& +    +  +       +    +        + +  + + +  +   !   +  +!     +   +     !% " +            +  +     ( ‚‹ gX sTqf#-'0(K3>8;3%,C(!$%.1C" /*!)1 "$ $"%#1&3:%$3%$'/+2&(5,"5"#'$3-.2C6CYGŒ¬M´ Aef1L="$)).0-#@!159LbB 6,+*<>$=G''-$$-;=AY07K0-DI4HCJ#UZ1_k@0KK!(> )&&!!)7CxŽ<>`E3V*    !+ 62D/4=1:D,<;+0@@GT?H]&JR'@K:5E<-=6,7:7@62?@*9I"2<-?O6KG=M=IZ2GT/34<(BECV44:1 /<.C;G`2fk,CD5?JJ@eCIT.)3)!,.%11(977I@ZeE6=0*:21?M+.90C@+;C/+1D#:C#5 $"'%=?@FUTYZO'U1         + &! "&%(%%03D9Si/OW=UaLCUG-<<&74-+%**2=.^d6}n.zh&VC!/,8"50 4>1L<,B-*>#1)<,5@'&01I=ZA9P.7M3R[;HU(7;12 5;$?@)3994F9>J0/*;*@*)?$)7&*=$E&.1"  +   +  +  + + +     +  +         ""($*, 74/C&+?-"7,+4($)-%)&(-?!)1#*4,+73>%A*%"("8( LEDI$?)0$%;*$$+'(2    (&$+#6)2%!3$/0&   9&&:#$+5#4*   !        + + +       +  + +  +   +    +  +      +  + & + +    +   +  +     +   +  +  +   +          + + P#–.*-F§5{¤Tu“bœxi[`‚¦c¤W:LHJf8[q-r€$fn@‡£vˆ¨Tˆ§¥SŸ4h¥²‹ž¾%1A,6020.+,4%-7 $3!%+!BB4>$/&!!%3#$/$EYMm¦š~³sŒ–Mz”Hko`ixj%F54(15LC 2= *..pq*@YL[!225+EVL>U--7.DO'!2(&5895ss0O\0€a)aS$*6(21œFS!)!n~'Š7HdA4NG'%(         #@$:K+:Q?XH-:5!)-##!+*6MOlrf”nd‹^q‚=AT"H>$6A+=G2NO)LB8/.3-7D+8!( &+7"7*0;1L=8S5L\)MZ%W_(OX0Vf6di#8D0@0%1/7+.N9 :Q&0@-C7'-K)#4.)#$)$$,%&    +                +    $)$" * ,*(-,+"'!!#$%*#*!)&/*0">5)*J#:1=C6F@=9N 9K5:H+7J/C)12&%!. %  +  #$*!# '$#&-!*& %!''!)'#((*" %#*     + +  +      +           +  + +   +    +  + +  +    +     + +  &#3#!'  '!*    + + + + +       + +       + +         , (ƒŸ9_Œ=jQN–ÄpW’\¨}lŒn‡:In7OYPV[s‚t`–Žun˜Š4a€4>V+3A//‰@E˜GI0M?AB%8627%-#/!/- +/0,.=$%(, >=*/$"/+Mv…lJyƒXŒv`lOtlaŽ\Lk%1D-0A6.L=+0-.@35Mkbi:$34$&/D(!:B*A+/:.3>813(31DD*?]=I]GncJd=GVRBM9ep8Y_<_mMcyQlx@Qj+EQ&0>%-=/7,.""()4,&<3,B93LBGm@_p7SoDg~NsMx–Dp†@kyaWMu\kŒT{›_„›i…£q{Ÿkf—jx_x’Wg‰^f…ZgURqYX~nq”yŒ·v€fv˜\wŽQj‚Sh…QXs? + +    !  "  ""(&&,%)##&! %'&  "&"   $ . 3% ,,70/9*4,3348;F>?C%4Q+K"1A3!<+#A) 4.2&$0#*!!!AIKOR3@O13M&>D'M%*M2/+!",)""    +    +   +  +  +    +  +  +      %"' % % "/&.29.76*>-<-D!$=278"0G+?J3)H'H?.-C'!1%55(;K%L!%!#+*!2 *"  %(* #"$$*""&"!$%#*!+' ' '"&'*'&% %     + " + + + +   +          + + +   +      +   + +  +  +         2)*"' #$($ +  + +   + +        + +        + +  +     " !!"}\#S:[›^~ec’ˆ;zmE_vTe2=a7YrS`žuK„‡2:c #1I>-DL!-&6G,QZ0@K;5Q1=I'.9"#*00GF ,@ $5$:7$ 1C@ |£,†–:¶©#[Oz;Oq_RfL=WNaoMC[UX_[Pe>0;++ .&+"+'+)0!0MR`qiWk.Sj(qb%<0&*445E#=9 84*VO)$0=.3J&=72R+]R)Qb2EL9/757G.8A7(4!4%    "(024'./. %$((99&-43:"#$#()*01#[X6jw?{ƒE†…Efg0DJ+V^&DH51$%$56*5>.;=2eYQjSWqSc|PdxJ`nL\nWn„du›mmdz‘anŠN]zPNjHN`= + + + +  +  &#$%$#!+"*!('     " !, / ( "* $)'#-(/209C7%=K!1I*,9(077CA:*@R*:B4C,'94&@)$41&2$!*") ) # !; KO#GY=0d>+A7(3/&<-8/*'#,1,1'ˆ|7`fw`.VODEV13?/,1/=E',3$2"-41".(($,0 /ODIdm—‰Á£t–B:OiHNDLZ<H_TU^Cd{Abx8 .,")#) %*Pp†LDfC*I`WŒXNx(_r+4R:Xa2IQ4hDLY"]Q!)*".BAu'()%'  && $& 0*-PF TW-Xc+EB)91*[JMI!0584,(! !$$J? 9:%3=>@\cRpt_~u]yWzQDPACR@?H3:J*07%:K1Wd4bh=ZgGM^S;K?&):". (!*"' #,$+6(!/.0F/CO$:B',(-;6C4<$.3-GDRfIVkNRnNPmPC]D8T=?U12M;@]HXrRXr?N[13I&0E,KX:OgUfˆ_g‚Y`pF;Q6'419JFWjEeuRdrGUjAOkEUoSiƒ[j|\VnVKnUMcKRjERe;O_6 +   # "    !% $%#!"$ )#  0 ":,"&()&- 20*!)0*,,/36);:%+G)1>4H5-DI)9I'BG(AG-H55E8%41+/('/&!* " ' !5NA)8]>7IH9@3&C$/!$$!9"'5A;@+7K+.I1='"    + +   +      + + +   +  +   +       !' #+'(;)<&'5"741'7B!->(+"/02-)40=+%@359.4I);J:jO:Us;Ne9#[$*$%).%&#./00'6%  + ' *"" ?(/G(*1#*7B+DC1I#5!$" (, &(!M0(O!)*(#%7C7 /O#">%%(#++' !!"  +  +       # +      +  + +    + +             +  +       + + +  + ++!1:02*    + +   + +        +          +%"$&1439#,1'8<%:9'%0&-!!'.*(-*-3//9+-=M/8IBPEbf[O{eƒ—z¡°b¢¹nn C3@9:K%@7'%22,F$ $ *"%"#" /.)6!#;,,‰mTl›gc†€ŽÌY67!8>&0DHN:M\>CSFDU`opI,3"#*$9#/>7<@&,00!2[FS-RT+->\QQC6TF2D67HM7[E;W^UeNeˆ7Af'7C(*-&/aD/,!"0!%<16 057%-      + .+TB71++ML7~ˆQz€FtKjt9‰4í¼PÔÁ9Õ–+Ÿ‡,kq!OSaSVQ1x@up0MPN$V?5O?Z@CU:fOet'4G60D%#! %(-'*-33E+#6*)B%':(2%'5%(;#0''9/3@)3.0D+9G%4@(39 1#0B-':24H7P`+IU1FW@N_2);0."-2 =" ++#&,- ##"+!0%0-%"( 7( 4B$@.$30 3/+5' + +         + +  + + +         +  !!$"%%&*$$-(*4!)('4'3G4YVH_E %" ( $(-/); -99=$aLPfpgiugpqr#_siZ`|Z{iPD‰=X*4V0EE>&:ULT!F`C.\>6./%F$2("!0(%*4-70<" #"      +   +   + + +  +  + +   + + +  +  + +  +  +       +   + +    +     +  #!((&!"& &  $&.-&-< /7(;B$';  + + +  +   +      +  + +  +   ' $     8?!-YA?i,02!,-%('1 +$!(DF4;B 024B":@"53$C>%14')("));5LV+@XH!*))(%!C8:">M)5=,=H.D:5*4/;(P1_M35;BEG MP%0U66I5`X?bˆ;UDYŽZL~I.cL>HEFg8JXR;U30X)7J+UL2cf3=s09EA0H@,D&(91!+#!5 :&!!!!*%"!!)"'+   ":(3 + +   + + + + + +  + + + + +  +  + + + +       + +  + + +   +  +  +        + "  #/-+',#)!#+#$  + + *""/5++2"'+'')' 2+$+&)   + + . +;9 95 D< @4 >A %0    $$$1 +   %'=:7AH0%S!##-)$&3;E3:G)?H*>B,8A"Z]1Xc'Q]CV1=&AM8NR4DS44H/=U9BK1;H(*A#(- &$84-KU>0M&36 7A#,6"%"**;6:''I !:6Cf6I$1FF($5-+) :DFKb^WoW0\J$DE?O#_`"X}%/ #4-$!39K'2<05$.(4-2CAA8/@:?L#*/>P%2O6:=CC?F*;G*4>CHVEx-JL%6G+. (  )36A +"$/1*JHJ\G1D@;ARws\]_^NSOa]8VVDUTYnmZXVWVji~‰C‰ŠD~Iz{P{L2K7)?EKUJ_a-FE%>E1@P*;E2)A2-?%$( !*/5?SOUƒS†¨7‚“%mpWUA>@?8;(-)( )'0&6)2%((4#7I1BO9@O(+;#.@'7K&+=&5D6DYBUf7Vh7Vd/@G4;[Ej|PpŠKr‰?L[61B8;V@@XMGnTSk>HUKIgPmQhtKQc=J[7>V6AL73A:AU3 +    $'&1'/**2&*)'")"'!)%,6!%!$  ( -"0-*4#./#48&482,>1,3-5.(0/#:5$19!9"))"!>$+@5&A?!9B!&;".)6*! 2-!"#   / +1629&+1(   3",<!4-*%*+&#0$ (, + +$2+   +   +   +     +   + +  " "$#'&+'#2'+$9I=7HX/HN*CTBW3.TF/>FkD1w}'i•,j~6hŽ+Sx87cC5?-)5.7$":*,)$4?1:B&@C&AG:NQFQbBQb?+V?#3$.5'KE+eU.\e*]R&gi'bBcvK.[/D3&!="(((-%K(/C$!&0$HD:L*E)',7$/ !%)% !&+)))/'  +"  + + +     +  + + +      + +  +  + + +  + +  +   + + +   + %   #0 +  "$#$1+ $0,/5"  -1!-7'16)",13$1(/.2 ).'0  + ',-11/714A3CK6BI7C$ +   +H*vTŸ—r€_2J4  +.*@P&^a7+H$"'&#$>?;<5L3BP/NL-?A-8P*YiHo}FSd>AU379':@/>A89L8:K17G/=S54A/&4!&  '#,&%15*2#4,%(,(2!L)B52S- ($"#/$4-#9!'65C(-@0<57EA?H;tS#CH"G:0ONB36?9$T4&#)"(.&--%**)/-&:L45a41)*5./5!65*99&1=18E4S]5>A*JK-\a3asTd}_Ok7i{,>J/;>?09%#"&*"7#2>&,=64:DH1GP-GN/2:5+E50>-8DM:]_B[HAIEL[N4RLmŠhl’k…˜\skX}lKur:d`BjnW€G9B&4<5RiZa‡Kiy5hg16 * &60,WfAXpbvŽ[j‚NPdA=I5*@61E1,;32@.         (#$%  !"-"/3'5(*-)'/",* 40,@&7&%+%* +  & +'&2-32+5%)3$77&A<,6B05:)<5(5;*$>'*+!+<%JH >R.2J.!=12%4=& 0&"-$ -@0' 2 K1AQ"8M)=@*2A#:6=;A90?08&,8#1&"9! 3=&5"%*#(!%"*;     /1). +        .#,.*25:?+@!:26=,;33P1 UK^]4Ye@Ir97_F;EAS=.mc#H}D]^YOlKDYUKXNljBGs6/F%15Q6"A] N$3/;B%GL)bI+Vo/Av:5PBU=!aNYpZj2!#,,8'45(!& @&$/#';,#0##71+M-#        +    + + +   +    +   +   +   + + +  + + + + +   +  + +   + +- F+ ]` eeGh  + +   +( )# '*'3'".!( .(". #"0*$-7)3? /:'(8%%%!,)24"*7$(0  9=(0#.!39#;?-=E0*6;43" +    R(“Ž*h©^€˜ˆY–G€ƒ'JHM;<+ +"4>,?N./LF.4/(# "-(@H5HP0DI0Ra5gpE^v35J0XRJesWY@J[5CA(E>,W\/hv4Zf02>/1C0(9'<4 %&-. +9267('%$(("R+d9 Z=),3+)-&"!%'0;''%*BN,G]*:I39O7dokj;ƒ‹@Z7WQ*^V&‹O.pR08$% !$($O5$/*:&-B2::1&4;=!+7+(;1@U'!$'#>/;H:FC]†FBnWHlN8PK%7GNTPhl'>D&;K%!-$*%,(3 "") &%"7?+I^4@T9ISD=Y6>N&4B),9+&2.#5>.B:S^5'7F)49%4r$:m1Eq&HV%2X-E(>'J#:M:D,TRAOdU7O`LnclVZq39H(BM%>L&:B#GM(Q\8J^R=DT;9P0EU)Q]$CJ";G,BK+:M*8C#2= 16.9%8>+P\;nu"KE*0@#(6!/()<5:UBJfMGdFdo:F[AGe?es@O^EN`(9H$IO2M]7RcAOiF[pG`sYoŒ]byAHb8V%3J045"*<)7'!3'(+"2"      ") 0 +% " .073(/21   +     + 0) (6!*"+%<2=CKD,UV/Sa'Bg1NQ1XX%Re(Ci5=RG0RN2GH4DE?F5bS.t@r“eOn=(mD5FA5H=EG+@ !0)23&4& . :!( 0'(8#4*         +      +  +   + + +  C$ @? #%  +  +   + + +   +H3OC$  +    6 DK;L+SOECZZS`RF    +-!+"$$&++0$$ "*0&.&( "/%$$%)31,.-,0$$ %#(*&4=*12#7@+A,*-(/368)@G6XL7YT(:2  +   !($/_15k+@dWfxF…vafryžJŠ“Awœ3gYc$@E.7I&G/$4R#*")?H5?JC5MWAOPB\/SI:woE€‡Gk|;{•>dr<0L>BIRWiG3?(>H&6A#CH*(6$"91#7EAva *J1@1'‹Jœdqu288QC;.0,GK2>WPIXShfMif9sfIÿèBÿØNª0Rm":?09,8,)1<'0*:(*!%/+*,"(13.@!GJ+\T14<;@ c[4fn:j‰Vj~46H4;K%PE(DOUvH‰|(7I"2=.;.8,1'/ )* JI &3"%5%1>05>6FC'3=/)%(!/!)0,6"4:07L07A5<%5E+3?*&1.))! "%)71ETAOaK_sEuu9ALVJ3MaCPk8GT#&)!%) (4,4=7(84'8=@g?OZ/*6@2WBh}8Ma3LW-=R54L2GV:?UFIaFE]PMlLOf8=O..C$!1(%;37J.-9&*%   + + + + + +  + &"!!#1$%3"-''$!('+3(2'$2$!-&#!  + . +*1-/ 6. .5$&.(,* +1!14,A4*4C$=3%6:'G5&MA'RM%QR*N]8RdD;_C>3>C&ƒ&"ES#048' $$8Z*3:':%,,4;:AD@AA;IA+>I02F>,79B3.7F74M:2E;6<71B,'=&,-@-!2J*;! 0       #"  . 5- (<=*[K1Rk6V^5Uf:]\-Yq'Ng3BI1D:4?:(MJ,SWCO[8CX@DQ4ZMC_f@Aq,DO=6F<180<=/;R3+<. -*+J4'?I21/">) "* '" #0(!        +   +     +    +   +D(SNCOV4;G%  +%!  +   + $601EH '   +    %0631KO[:H!'&&*#+&$( )9 &$  #1-1&(/,(3*(-%(!)* 4:0);'@3(6R%JS!OT%MC-vw?|Is’VŠžD‚#‚wQi$!#$. T,8?!/+ 4**=P[SGSc–“t“qUyQa\FAS7HT,3J4">*"!$,4@0-80DS1N[2+;+)3/52,@B4EWMZ]XZiMl~gf}MGW%,43,d˜7PrCFa */262/]o^¦ŸT¥…B€d-gk;BM')<J3A JS.9H8)!'', %#&+,#1%'"&%''4$*6$,:)(2'7E(IT(;H#>N"47.7(0'% (! -/ 4B(CD-EpDlF(@++91':.2D,Rf:_qFh…Fn‰GlzJb~Xd„O_~0\f+js-{‰:{‘Dt‰6?P)FQ+;H7/G@F`JWuHaw6Sa,=K,@R,DW.[l,[`0=J=J;GU&=D%/$'.#0*'' $   + + +     !$(&&1!(!& $"#,'70/5 5$    # #.)'/1'5&$2'*/'@6$ME SN-JR/N31C6<0=69.I:,RU+SY9G^4LM&QP3L[,TR(@e "S,-*!(!.)*/$0"0-& )() ) % ('(!!0$43/, + + + "!!(&"/3@>EL"E%+80 CD34V?%GF/5=+>.8+ )4/#%2+%%# /3$D2.[R/VqFPoWM\M_R-Ma@U!AI1PQ1XdDXb2*:)30$-45 5*,)4.48!GN3Bb*?@:P)6,!27&-$&$&   + +    + + +   +     +          +  +" F=#U]CaaJly@[w(SXFH.L$4  +  +  + !JF5BT 9    + .' 27'8,9)5>(9H"?:! 1-83GC Vc.TZDJYB[A?1 E7#12"%372Y^;A&2)(##+),#"'!*1(0)8!),'#0(&6-)-16+-U]CFcP[nadsqUpq@ay:iE O(79205'0!,NBP`4V] %3 ",,b¬;Џ6Tcnž«‡‚”WaŒWj‹?kg7?`.'>*'0+25 ;I+?E#7I62BB4>#79$0%))-3B6QUD[jEavXakK@R);<&/#50?ES06@/\c2TaHUjK:N$+/%'!!.0%C+#oI2dA3žg;YjFOzG\C=A;E;,fy<1%WF@ïÌoÖÿtV±X^o@@N+/1*f~TK tNw^kkPØ®K“¤AAc98GHS 3H)7=%2;'IT&#-!*!$#+&13DT6LdRNgMk…T_iFIY7LZeH^Nq‡M[tHUsCIXR8F>=M)9I&/?/0>0LW7BN-%90'=2#$  %$--2#-%2&,)$*(%.!&2!$,!%,!27,@Q.@O*7M).A%&5!$-$",+3.< &0(('*@0:#/"#1$#0%*636JC_|J^vUm‡V`€J\tLgNnˆIkˆNhX_ƒW_Se‰Ho}1eu4?I!'246C@-EE4QGUu:JU1=M6HZ@LlC_z9Xb2[h.DF+)!&-C[{+WZ)'766N6JM!/7'8-&>6'@21J*1C+6J33G@HX7^h9?#)!"& % +"      $$%%%$$&1-+>6'"  +  )$1*%70%'&O+PHIU$FM0UQ6VX:O_MSSW[PKgID\S8S=7</%C5 +#'#*4*&6;..-.42& % 8$ %;#0&#%5)C>":K8UAGEZ?NPIF[9*UE,97540GH4_R9Tu<5Z@3F>SJICW1%Z<'(-*C5>_?5Hb60JW?.OW&=S-0;*N:6F('D*"0/'9&/&3!#+ ()$ ! $           + + +  +  + +  +  + +  +  *(*5AI=JH>OS6GXNTDIY;,D/!+2"  + +  + + +   '!05.CR8'1 .646+$/& 7##B9HP'KS/\f;GeO8WCWQVbn:nvEYo@js:Vy55(OBEhgCYp A*F3#D=!3:$),%*-"&2%!$&&, ,&$"+>%&6;*3:CGKFIP7LO:C!8"N1%L^-CK!A5`\0PˆIPb(@F:?ŠQ_žQl‚g…|3‚v“h}gNukXVQVn6g\#>REC%LN,IP14B*2?08D2BM-4C*,9#.K@+X]@DVALOI~‘P‘3Zp(Q6 0^/(-"&$*2OAO#K9>.SR"-!#<*G9&zY>‡R?˜‚;VHMP=730O/'Šx6NhG79'7>G6Yª6Z€;KJˆ‚FÀ«9»ê-PŠI)9:ac?”ÔkH‘UxUYz.3>,7L43H&&,$/33CB!0/><*,7%%/*%"&,.8hM0@A@N;?jJI`KBW6;Q14H(XA+F<.I?CgMInUPtTRpURiLYkJ_yT|”FXk74F%#1%/)+-/964M@Yj1DS6GVXq8[c#AE2- +   "19P@Qc"9@";F-8G"6:(1+!*$);%6H)?a3Xc!)XP1WeBHpJc_K\s4Lp@NeEN^E\cFTh7BW58J"FB"?>=DM5BT67JE,E&16%'7)#"2.75=A"2?>+;316*61(2136)7,%#%-&'5!12 ,*#-$')$,,2!%9%1"544=J;2W":8"-?&804&P62F[,1QDEC>GN88V<78&G9hQ)Zn9GnG;WG-2.@"*18E84DLGH[R'Ja84XC296AB(QQRR/Q\IK[D5P5=5G^P[]ZghRIqUxuMoz[VB\+dQPevTbw3RI3 %0DL2H`8QV4XY)N_ 1M(3!,0 '( >)*6.3$"/74$3;16<>%A+'<..8?>AFWHJKE6=3%'H)=@DOHNdAIh=8Y2`V^aI…N~{w@M&,.(;D#0B26"#,,*.#'5#&'- ..!"&.'1 =K;DQ@GQ96M57H+)6#0<2&9/3G3/A*&7&.="NT*MW(5F!66 :L0+;"/3=$ "$',&*@L.?-#"%-#- ,$3 ":$- /;.8G-=E$)2&1$*'()%%",'@$0L,9$;H17K68G:,E.BW&4F'=M9YnD_s7JX&AK'$ + +  +  &'5&=L#CH$/&0$4)3M+AU+?M':E41E8=\2LZ&0;++,9!#0'"# "%!  +  !"!  #"#'''0%' /)$820",7%.9':6!9F<>0QL7Sa?VbEMc@EZGRT;I]BET@6K<@<3:;.=,,5*A,9•23QgO3BP4&.2%)* $(#3,)+'+(#0,.416$29,6C*FFBPXDBa<5\?3EFBDBBZ=?T@>V7FX=M\4LX-<`4=O:BD.2G#+E!%4#>0%EE';X/8LH2M>8J?>B-,@!(;#/.+3$(7(C;=H+*G1"8= ,1/&--)27+);%"8'&0032((3(-31&2 %*(0%60':2,%6-) 0'9C)?+%4E*6?G" H.%"#*'"">7#.<>+!@O1L]55S.E=*JW24RP6CFCD5>U-#6"3 N@V_6:Q;6G=!2()",         ()*#># -*++/.0(+2-1  %")JT"JG*OT6L\B4E3>LG,<57E@?BH'DQ(9K*!IY_`_jYXdITlFJPXJS\MOX8IU.1X#;$ !/%0,()/, 3@,1300:-TK$[dX]NV-T]-SZ2brDZe>W]2JJBH%`a:G\CNP5X\,4T686l^SG„Vw—CreB†«wv–ƒ‰ƒ•x~Ÿtx‘XU~DU2BS4GZ*1C%.'ED/_g>_kaFlG9_0-!N3GP(7*"'$4=%B7?L"B>&tq€Xvyt…ffgr9i…:)%O4.:>D&9>8E*ÆXµ–Z±“(0K% *>=PéQ˜´XuC5I%%-%+1*687NV4UL.y^8Š1_o->&,1 &.%'<> .7 0!#!&& ,#0:%!0-*03'C(#-')6&.7BT&CL+:"(7 2;"E`(5L4CW/aa(T]!@L(DF>D?Q6=("$!$)&&-"(6%7B.ER'8@.0#3#)%!  $"-&'4%49(3E(&5(3&')!2-2F+J_5On2ReARoQ[€LwŒHTgMXxT]@G_ :>$&#"&2=6XmO‹šNiBawCf|KmŒHiu6bq0U[@>;AA=;/$!7@17J/G\+AH'BP'FZ2[g%9B9C!3=-3@84E:3R5S_12G67L4?KAOI7B[26X=)G510#A;*N.#9L25+-72:56E+D89I>-?:*5#+/!;1,D #4'#+'")+#'$-/%,8(0$0('#4#&*&+, $5)&)&.0*;;/AE$B8!)I302#%#"&- F,@GEE04K)J;-DE JL4@R3%;*97)@<3dX,Ud 5[.4J;"BG-3/0=39;00:2B@,7G"3K/*52631>I45F=/A?":=,WQPY8SPM/B&E(('2*%QZGTaNRWKGTBDK+>H!%/0(,:!$.")62!;A/7@*88&MO97ZOJUNUdCYdLdjNo}QY|PZeLSm>,?03$JT.aZ7~‚2\_PbkD~xl€º`^w;l4y„8GE>G!($$4.#!"%"!%*")1!1>67M/CQ:;.> 14)QQ+ji1amG‡Œ=€:‚”4Qk)CM/8J'RS&&"AK,Ob+5G$5G&6B(" $#&(!,!7<3JY0Zh'SZ 2>&)&"""  !%!,"-5%/8$-5()69LP&YX4hx>Pm=h{9H\EMiNc‰Nev=N_MSe?EO+5G!,5.4CB$SP5mUd…XS€F\{Ac{DRtCc‰Nˆ¦Sr‹CSh9Nh2@K&8N+BT&6 ',7&6>3Oj:hz2]i8dx;aw-AH&L99OC?]H]x;Ql..++)& %$$  !'"  !#""*"(-)./#" +!%%'$&03.5:#1?&55)??&CE5EM0;O=@C=EG8NR0B@(BJ+IK4PU/KcGF[S62?($0&%+,!-;B,/BE'AN>6RG9F=8@34@3,9:18(,D'0:%-93%7#", %$#') . &))+%2 '(/-0578(8.! 01IB'AM/*G4%*!0*45&,@?<DF9JT.BW;,P((344--;J1,C1%: I+)XS",eN7K6)*7**33%2A-99'/@1.1/25%2&(-/+1"6--#$ "4%6D5?(:"#%     !#      +        + + + + + +     +    + +  (&1B@2&H M:;KL3FSF,S@.61*(13+?9UX>bGFl_-Zo%]d\^^_!Xg3AQ8,7A%/&(($ F/GP$#:+($7 BH+BlPYsCjt!b| ;J?1<5TN4fi:ƒ‡Gx…CnŠUbO^u=De"*C/^F>]gLS[H^R,]['K\L4MB0=;&K/!'"')!3;,<8/3*'3,/>:'eM2OX90@(":**97;2Q]QXoPFjQ(9U3KTMMDk_ApAps@]}8jbSFR=`g00B10*-J2A`h@bxB’š\¨wgšmh†\xˆp@sT?JM@I21A2?E2:M8>M>::%-2*)*3<@*FV64MbS=~€KŒkZ£04W03$:@Rjeczr<ŒŒ<š}LÚ¹T¤°xÿÿg¹¹e’©h_j2>I4[h19Y0+2"&*-%4 +/*/!*/69;0;7M&1N*_h&8K#7C!ER-Sg@WnArwO‚’Zv[r„Vo3PP(KL*Z^(PO$M[0Pa/PT!5H2Je+CT,8!,%.4A!AV 5D+>*%9=8S@Pg.1D+$(    $"/%4%-=&9H%P\%cr/Pq?TrBl†Ix~FUv=ax;dsA`mNXn9HUBHf>ET(5@*KX*Ya5z‹B„Hk„PE^:,E@QkLxšLˆ¡Q§a†«ZYz=@O5BR4HT'6A4.C%%*"#/6 1>#6?10NCEjGQqFVtL\ƒ;fu4MU.0=(, #*&!79;O=T]5BV5<-2G86<78@0;K49B==C<8?301-W!T7&::7K.,B=3E.<:1'%$$ +! '"' #$%%0#(."$#"+%)+(".0&:9#BH2PQ0FR6,^JE:OCS<8S68C3:C,3?144 <$(  &!$7)5A+0CD4EB4H4*?/%:/92/0E%)<*5.' "#& +$(1 !#"%,* (5)..1:74C9=''@*$' ;$H@"IM38N37-M7/:.%6$ +"* "1* &N.CX-+DM2)(&1)(#:+ CB%8D)3D(5=+<> 7>#5B,"=*&%(0<%$=)&4$%3&3&;3: >0   +    +  + + +    +  + '% +,$ 0   +   +   + +  ,-/2=3>>>COD7J<2;$871=)MG'fY8ZkNOc3BhVI^[LcMObIhRGj[b[Ro/\€*(E!+.#$2?8"(--=,"&#"!/$5>).<:8UJZBFZ+SZ4aX}}nn‹o:UainaMkM`OE‚i.rŠ,o‰:ˆbKiLLeI8JSlIJKE>L?1[S#TLBC&-&.3AQIDHd>_W@^WEeg1BV5B9#Y:g!’›,ž—D•£P_q%?;#Z`.HYH~k_…’q‹˜`q†]…QU8AZK00-=/N<1YWS€oMo…x„—†Y|`b~cJraAo7-@-,?)4>%1=2.9/*>-(5/09E(TQ"5U+>=1"B,'/(->CM15&VI!WZ=‹‡;I\,9<$(4#5K7N^M^pRZ’d’ÕxtÈzI_mTd°D‰g=ZZ7K65I1CN:;K4BN(cwGbuYt‹ev˜g‚¬Z‚«Jq?o…:cx8~‘?›;f{7Ml//E24E0'7,$+"#%*$/,:'AM28J7OdDQa3[g:WmEiXu’i¶\…©Cky0io<’§[žÌjŸÉj‘»k²ÊXy>ˆŠ4~ƒ0R]0QX2Qc0gh%]]KN+@R3KV*AK6;G?CPA5PB>UFaASc/:?%!"&4*?DI];Pj:Sf5O[8>M6&") /'3 1 -!/05$1"6 2)#*#)$*"  !' $ $#!'&%!  &"'*. .!!     ##"&#!$#&##-+$*9.23077+5D21A43443!041+)(4%!+!+ !#!$)&, %(#)+!/%+%)3,'B<'=T28&)324 '(% 4$#.)'.G3CU;9N:GNc\\Ma?Q\XpidjvK-\#'=822<5!!0 *>!2<*NJ0Ke:MsH]n,FM.4(+'2%4H6=NCHaCZm:GU0>N0Q.Y/Z.a/X0W0V)M+U2[2 Z0^4Y0 N0O+N)?':$0"$!#"    !#$&      "#"& ""!" )"./0:,/5%-8((3'/0(,2')',!"#+81#$%+#$ "/&#/#*)+ -("+(-/,2#"/,!:*9D!BD9:J8.IB">55=&#,$2%!71,-+19)&6,.2.!9( .+*)*.*5$98,6A',=%0 #/$%2!+0+7/'7,  "&)#!'')%-0)91+#70)/3%/6"2:+&3#!%%" %')+"/#'"#0-3?HA$H;(4C<#85.(1  (1-5*,,./  +   +!!%!40+/EDH/A3(&4( 6)+=J8'M1*<2 8> ;C/1=!'.  + +       +' <74I0#1' (  +  + 4 DU*6@--<0461%<.N4$jlGeqVanY@`Y?D\CRU%B,!%$/-+(7%/dfRDb^hK4cH\T^ymNp„†vˆvf}hopZVi]DyLbKX&6X6?F\Q6dtfoaaogD_]Qi‰hX\?Yp?:uaf\Ytym‹‚c™žv‹¥z†”^”_q}`fKUU7CC,YH!,.$E7/FiBHT@u{DQsSieO6*.C*"*76>)/>21<%6A#)8%078P-5HR03_/*=(8;.:GO[!ae6fw::[:BY3°²A–?NdN}–wœ¿u€´v×옪ÿ˜q——ÿÅ¡‘ª€€€X‚£Wx·tŸ‚€´c‘´B‚{Ae…IdvLES]/A136+6>:+3;6<115<>K:FX)]`+”z&¼Ž DD,ef(DJ(K<51 5031/=44>;12B..3$8;EL*>K,VO4CE6bc3WX'/8$- (,*EG%37();+8D.0L>qƒ>t£C‹±`’¸blš^b‡Uc‡Wd‚MbWe…XožOp˜Zs–SxˆN‡“J¶²U £N´Çb~_a3IW""+&*,6,1'(+-MO,Ti2I^0(;")+CBa_&8\ (<%,(1$+%+"   ""%4IaP_yUZtOVxHYzGRmEJkDe|IRiRe{bq‘SoB[sCIcNes\…¡`Œ¨b„®n±t‡¹o·u‘¹~|¢‚¸su™|sžnHq^KkWJjWOyPVzSk‚bh‹bOiQGgDNe42C23HDYv+IP#BI%9M7RjP]z?]r2_h&N[$MQ+>L;BY?JcHQ`BGY8G]7¦K.¯G4±K.«P3¡T8ªK3«H6¢N3¢K0®J0ªJ1©K2ªM4ªJ9ªQ3¡M3¨K2¦K,¡H/@(};'v7g3P/=.+(($& "! "     + + + +  #") )(" '#&*+5()/%%2$#,$'-!))-*(198 !    !&"(!!  08.39%,7$)5"%-$-((,1'5!.0<,':(/- 5*.2!-6()$&"$ /. #:&.!+'!$&%%( '/$-)2&0;,7)&" %##-./<,;($4%+#!!(%%-&"(!H*CP%5D.066@(+;+66'1=#/2#2=!7"!##+#! 0$*5$2"@-'K2($6$!"  +  + +   &   +    !&1)0$=) 1,((-, C8%2C91/.()  +  + +   $#/90'1+")A%BG H>A@$#-" +   5*3*<-'2--+(4/@'$QlTOm^Pd\[iKem:ep>hv6N^%/*%,.0@APSY_40`I7IF1G"3U(?D'0C2$?,-%M@!onn^BH!*80/7,'4(BG).P/:)-2!M>)|‹Q{‹2bs8HbZcl_kˆsm‹baue?[NHKNN[U/T!(/)0;?COQl„OglO_AHW2eP O@40*&4*)/&,5&,92DTKSXOkx\s—dzJ‚šMˆ U‡¨M­O‘§SuRy—QlU±ZÁÜuãÿ}Õùn­Øzˆ·_™·H•¯6†”HJU^$WoKRJ\/_{BOeC:Y8Ja_\zu-[}1&@/ %+)9#1#1>09#&$,!$'5>?Y=A]B_€Iw”Diy?guP‚˜UpŠL_z\nYt†Q†žT™£T–¥h•³u‡«ch”|{¬r€¤w€¤kJq[,NY@cZOa]P]B9@21>32E:BVGMnO`r^[vUTdAJXDH[5R`'AD65G;Sa/@Q.AT9:T?AZ@Bb=Ro8Ue7Lg8N\6:IB=QR@XCAX?EQDl=FxCIz@D}EB|EK‚EKƒFJ‰JD„DI„DI‡FH„AQˆBKŽGLKN•MQ›JJ–NM•HMœMQ“MH”GC•K@I=ŠC9{A6j>/d6%K6"B0#*,&%!      + +  )&+% "$ !)$"$!$'#+ $%&#50$7" 6"83&0  !""%.#*!&"#%! #-+-6'35/.5'.8!):791=/8$22)7!/*$"## #'# &#6",A*2%"""$'-"$%&$2.#  ."+7%"6,+,&&%! %" & $)! ')6D:AJ54I=3>35E+2>958E># H&0&)-)2+*#") "&'*%/ +#6*1*$ +  +      */)& .       '%5Q7KZ(F\?*L+)   + +   *#2.(IA$OU$Qa;YZC^]HM^2!7!'   +  .1#-C*&4)$6"#.**:$<92>EN:;hH>aSBVV>fV WNJ@5:Q&+-)7/$'BUG39376"9E&&:!U@6CV&(7%4(&VnHj‚hTx\0V!'9;0&=7#6'79>N*32-X.EjR_VQzAC]K^nobzx^†`X~CJX7nYE>W2:?''5%,4-0BRZWS‚z7Sta/HQMt59Y9*GDF*MT%,.&6D2:>+2=pF*aK;>;5AE-;F.DD);095)53:E$06"&6>4gs8~”Lm“Tk“^†¬]š¶f›¿j›·n•¸c~²Rw—Lt‰[fn~¦ Ü§ªê‡§Íl`~ow›m_hm©Su©8qœGz—CMGG"3D":B%8D$7K$J:(   +!:=,30 "% +#J<BU,%RGA7HMUB3OIU\K:P7?>7B- +   ('*+%'%",#";2!,2(*.-& -:5!&%#71E%-0A15Ai0:;AM4*H)2;+;IF@#$%A1a3O',"%+=$(&/35UW9}Š4n|VvM_5CQ@5D.,:rmPyiqƒgn{†’ƒ™˜ˆƒšxs\J>T6-B5!,""4/11D@*LH598!+; (5$$(73)HJ-L213&,A'&2A(:;5C// +&/6&|Z&Œœe‰Ÿh¢_ ¸fÿãdrÂYmšGeveZr\p”jS}`XwsŽºØ¸Î…ˆªGnw1‚ˆJ^}MazOVrgDRGMDBNGJ5>N=DWEWYRh4GVdOtyy€c=…p;X`ˆ>UsNo<-R/ 3(&!'&"%,)D:&89 :7%,-#FE%B0?OK1UC.B;)=6$C;#^DQGO?^K0Pn/+<445?.PjP[„Of‡DFbKm†aŸÐmÐlq¤hj—ct•VT}??gC0MAMf[§z޲t}“\_ˆIX‚R£J^lKj{L^zZ€ _ Sm~>R_)=T&@eGƒ•AVg((0#!+$+/.)((<$#, +!#  +*400N<5LD;ZH5RE-D>);=7C73I;ASW_uZZudo†gab‡¥FZtFd‚F]wVRzIIf1D[0Na-GO*0AQM`SizJKePpˆDs}7Uf?fu?L_Ka{cj…cl‡`a€Rg‚=z‹=q„:uƒ=s}@:Q\=Kb@U_;7F96V>EX@H^3BJ66C@M^J`qI*$*,!/ - -#'$-$/$+&0"/"1$0)2(4'2)1+;&8+B*B!(A%/B!1?".A!.C*E#1;!.-#.&#)'+!&!!! #$$"!& ') 0",#)   # !!$&#,%+-, ($('(/!+& " &-%65(I 3*.)66+:#-6!:7/F!$5")-!'0#).,/!3< .>"#:)#,(*#- !)#-$,3%.*"-$ (4&8$ 5-), "'((*#$  +         #/&*6-  +  &+%5-/<-0/70-" 7%+(#&'#$ -28;.:C:@I7#KO#%3.$*) *'&) (   +  +%7!(   +$+ %+#2 " '%>)P=GG!F29(&"  +   + ?LB DS;L(DQ7MK37N&'5#& !5/#3);'$:AH=BX7YD7N_,&7 +6SLR['Fb 1'*"63 (7$&!!"" -4?2*.@'PP@CV+>L9/B*-0!2A'&R0  %(M)%T0, $!&,,BV+HO8EK6F7.83$:+28=B)6P64UM>G91@-<;!49='A&%' ""')8itaDSEia5>L}8]Šd‰]E\ 7>&DFEbk^=TR8EXa~‚W€n^ps{‰m~‚p—³}›¼hEj@>Zmi…}€lntg_U[8AR'11""7-A"HA,>Q6=@.,@);G%LO41],1N40 *,##1"',"'#"(-@K%GV,bd'8Q(+=#.7 2=14A*?B$JR'6:VA6¶°_ßõz·Ôiš°fh‰y¥ÿ½úlŽŸdžWk›Rx–WInH]lPfiku’ŒÁ}UrYÅSgv,=*-; 8A#J\'E\4N[?]H›²3†žXŒ°pl«_n†T|—Kw‡Jg.6D"(?),F<`‚`T{bKgSmƒ>NaJf‰U®E›ºUp‘Qt“m¤½^¢·Kp“7Da)!432OELl-LO:A%,&-))1$ * #  +=BCK5? "2)**,+.'.!"1#+;&1<-Kc;l…H\r@FbYkŠkšVkŠUt—KlŒFr‡;Zg1Nc4Vl8JT(CKAQdXk‡LWoOg…az•Q{‹Ns”IrMc„Xdƒ^l`™Z–¥Q|MQvVw¥OsQ_|DDT8APHH]?V_)@P7KcE[o?Wi9G^DNp\b~V!        +  )0!,'.',$. //.!,+!(&*#()('"''##&& #%! ') /&##  %"!!&&)/)5/'$$# ( ,('# ")%!:*7+,2#73>?*H),:0)8!':0$1(('!,,,5!182; "@")3**70$ "&$*!/0")6$0$!* ()2&!&   " -#(4',!*+''    +       *!&,$."  !5,"7;$ZB'*C(-# &%#"$.(',>.#<5" #"".&  +0 99+5,'(.."#", %/!%  +   P, TPMIL7KO!>M8/@G!.9+ ;* $) )$    +! +-;#87.9?1?C!,3G09CPC;D2-8!#  + +, ;%'_Y4\c?Y]XP[=JI=EVX_f:hoOTmPBR12.&3-# "1  %$#;? 3.H8/]UFCW.3A" 5 -2",( + !%<$)-'6 !-%$%$-$!1#&D5CN)H?0HS2HJ2WS&}m5‡~!Eg2BC! W1N;Q8MRECp;0;(3HSL`75>0==-@NH7T0>E!_jAM\Hƒ~Mm‚`Yd_h}†ad{t†U,;837?e_Tkyaž‘C?V*7I!":IH!M[6@U5.D+/;!=')8G-1F,(+$  "*0*058'9 !;/.z‚2T3US-‹—Np‡v[P™ Æ¡…·~ršN6Ji=b¹†µtFWp…Š_Nˆ[^r>n„P^}V:M[6VieWFxx‘‹ÃR~¬LvŒB]ŠQ€®ð¹ÿt~’TzyI~™'†u?zyªÓ†x®¼z¡‰Mq^*7-7; (0)PGEC.8&KA9GNdiUP…‚i„hPmgO`u(`S$5>!D6%NB"C@&->54%B@"GL/Nd5Gb)Sf1ayLW‚h‹Èn±ãc“¼CYsH{šZP‡Ul3ZfEJ&//K]NFZ//FE\€Ur=‡ \~ªhp§a_ˆK\ƒo«m‰ªcDh<'7 '&)-B8K\2Qc2=19L(az;Yv.Mo'AP )'1*2)2.6 ($1%3JBQrRUu=UhMZwuKgN9Y_d‹^u•QoŒNmŽ.BZ;SpCm†4mvB]tXasVc„NcˆflŒ\tOHv[kŠVn‚OvŠUq]tšf€ªc{=?ORS{b{›SnŠBbo>EJ9=P?Pm8=17G&&7&&*$*)" K-PH"C  +  ,2N@;RS=MN30M  /;1.5 01*1)%&027;@=E69A-:520%  ;(NU?DgQX_UbkJUbC^o9Vd=cjRau\BbV+2?'A4"/  !!%!*"+*-2!/&%.<-9<BQAHK?%I+$-%#A, + 2# ++(3' .!'!  +*$&$+,%+-IL?\U6=EEAE]Ael6aP.KE#9# -6R/JF8G`;WP?B#KP@1P+95+dc/4V)(,))4DD3Imfj…egiP˜”c›´X[xai,G@%Yb>HDAGRr@QBJQ':;8K):@1HI+2@"0=1,79$$6$ -$0,0=¢‚k­.*A%;3HH)5@F16&gfJw¦…ž§Ue³tpl9RY5Xe4xr;{lQnTu˜S™¼…нvj”i^…:P[3LbqDeF^~jCMGlxMet`|“Om}*y{&F!8+'+ASHiGX…\[€PLoFE\8=ZTbmhˆQA] '.&(/+G^,Ja*CM=M hr"^g!cfTdV`CS:?!,3',297HDY'l{>e~EK\21K4(;& )'2D 4F#,= +1"$-86!=@Jn=7KH-B3&:?9_ZZwT_pQX|=]u7D^CBeIlšF[uKYqPYqMIlRX_dƒHZiCNlMWoQ[~OVyU[VQu_\z8Sc7Uhc”]rSUwHOX.?KFRgAMQ*/:-,/5!,7"7@'7F(9:" "        +  + +7055)4%/)%3*2, &()'&"!#(%%&"!'" )(!"%#%)!+#&(!+ #'#"!!'%&",&+).#,%-8-A,B)70'0'$,#/0")#"*"$!!$ %("'')"-0*8 .74:!?D":P*0H/6?&/C#A)!6,"2*!% ((& & )%/,!!) , )!)$  *" 71 %<3!$$"% & (#%+!"     + " ## "%! $* / ,(+(#2$+$ )" &!1-5>6#6!.451!3 !0! % 6-=@ 0J$EA69Y4FF*4K8?E26C"!EZ6H,1@7.MH@V[>RgLMRVQfQK_L5cQ;QWAH(&*! ( "!&))+;5'E(%"(##-&^p€Gnn7ecBg^)fm*AjKN\1TBOqQChNR[JZb>bV6ŠpaƒtÁTu¥N`VeNQQZSIRL,O?@SEEOnJTT;\YEhj>Q[4GP,DK*DC34?+3<#ET=t|;_v=DW29E-9G*"'*7 +G-B/RgL5Z9#*+5/CURVoL6;#&-$.18 CQ8g|FYn5Ml57@+?R75IH6KJ8Q(3@?SN<,;B(38,69+.3*#          + +,()/"")&/'#3++1!$,"$)$)%%',**'%%( %' %$ !#")$)!#$#&"& *& %$((+0+/(2%1)/--<& B)#.+)0" 0"3!5$*%* !(  "#!$+%044:;<*H&-@+7:&3E,*?8&:767*'F&&891/#'@(2 5$.#/(,%3&0!3*+5+.*1)8%/"-*,(9#51&)(+ &)&"#" '%0+75(9"' % . '##&&#($! +##*-,"+,!+# ) # !0!.728!:B"99)31*+1'&04.;#0.%8449@5K $F44,65N.B@@2Q3/5;.;0;82EB,$? "% &A&+)D8(,1 '2)))2(5*0!%,58)/ ),3396IB8B+<""& B3HJ$AV==T:7F2@C58G..27;+A)&/,&/'59,-?',-/3"(7!32AQ8=GGBAŠ„U{c€ŒU]PSRYTgxVouJaa;Qe+ii1Qf2^Z2@U;Q]OU_a‡‚j‘¤g~‹k ’h§D–]™Ðs«älŽ®SVS"IX1+:&+. <4 (,5R4-C6"3+I/"̘Y½Ä‡f“‘b|–X{X\K]p[´¸…|µn~“_s“=Œ”Hn€epbR¢²i—·[¸U¡º]s£~Z™šš¶×ˆÆÞ¡y¢]dlJ_‰:\nTvŒY[zF{f]°……ŒVUpi5_SHhh2H/3L0Misž£J¾ÕfŸ­d¯Ã4ÍÊnu¥‰½Ò—Æ€…”‡’ŽŽ`PDlGKa>jh.7@8DG2oo;ZkHVfVdudÍ¢ZöÚgqWPV?›F@b5=9)!8C;,E!.5+A #/92-!#.77<ST,{>lƒHmˆA~8Œ.q{&?I+hm2Xf"ce"jv(_p3]k%>N)?O*I_9Ok6HfDEdFJi=9M+2D=C`FLrESr/;W3Xi3h~9f}:Y|Yf‚hv¢l‡µa¦ÖVªÐE¨Ã2fr"3& %-*")!"'#"//(>,BL&,3D,SkPtšU›Mj‡St…:ag2Yl>[hDPpGB\@Oa9IY6w€1U^(2@32E00;/#2&! #   +      ! $ +)&%&& ("(%(( #)&&(&'%#/')-,$'$((%&!+&)(($*","/%*)#"% *"'"+#)+-++-0. 3381A$"?*2)6#2#6 <%+'!$()$(3,6:->.>$)<"*5)&?,.4+%:!'6* 3,+"&)()$+&2 )+!(.**(*'(-,)6#5%,"/**413>#3>,>#'0$/$."$)'+'+ . &+$('#$$&!!$&(%1)3;0<,.1%*.."2014%9 !" &  + # $($%&$/&8*#3D*6<'=@':I!2L&*9+,9 06'229B(8H,'<.1?!8A98G2.D6I8%!I%#**1,,+87,3D1&=(.5)-!*3<-,@,*4$'2"3,(")+*8*0D-A%37/065+:;=6(8L&27 /#/9"=?78E8)?6.;(4@*/@4-.&'9&+%!,"%" -)/6A+4F(E;6A!A1(3C384.4B@,A8201**:>1-8:580=C7AK>0F3*#"0*0#%308@>'L133"...9/9*;S8&S*D7-858<)PK/8K")2 2 ŠsOrmZvl;cC[‚8BlBTY[goJ>PBYtRzŒJnyM}y:evAmq^n)]o˜ªme‡(-)"IC)DN8?>/Jg90>'3@8T*2F6AYBhp=Wc8Zz?v‹=_u7Ne?WpJQjUTqcP…xl©yÑg‡¥+,;%3>$&?"($%#'*$!#".&33#.9'%5)$,#)%#4 !$!(( ! !  J +;0&!  )&2"",*):'67,1@,#7-/)),59#)J).?29A3+D.-4$-2'&2),02*E(-;@$.!'#.%!0#13-4J;0A(7C-.7+55#+>8!4%)"&!( 8;!6L,4C2,:--/)?3*8O1AE.DM>VQ+?U*.G#/*))5:886!#%&'!%)%$)($+/$4:+2D9<=D95E--B9=O=9A-@D7@N*,E)+-!*0>69C/8?,)E)*4,.028;/@ )90C(7''&6+$$+&#-=#0-&-<'),)36+ :$$&-/"3HL,*/.44#FRH)?*   KY=†d{DWc8_a08U69"'@").9<5v"!%)-0W'3F+74)95A/3LU>C4Gn=WmCXh:ZhADMek™aƒsg›©cn”W`aV>jBKcpNmk/F,7E$ÀrœŸX«»x­ái”¼:TeL>),%-$N8O9)…tI‹xd”s>z|4·¬xµÖx†¼IuŽ=—›C{œSo…T|¨rqŒP‰“WŒ~J¥º’ŠYp”eJaFpk1}œQP˜=d‚GH[_Š`Š‘q™Ñ}˜Ù[b€–nƒš^‚¬e\˜}t¤S0R>3=4vŒ˜µÙ¯êÿ¨îÿªŽÈŽ‚©‹£nj…lOdY†qZ¢¾ƒ¯²¥Ã‹dšOPdNkh>ÒÌ(¸•(»Š ‡j*PJ $5""5+):F&/N>DQkyV>W`mp:MI"**%-.%++*5;225!)2"/3")/#58(ED-0=5<&3"(87,=?=MQLeIEa2=@%>L4,1#&.#*)5#,+'*&9K!('u~Mi“[\€l‡©`kdrŸoT‚PQnLw›9r†N¼o“±Zpj4Oc9ˆ“4ËÇFÌßD’¤O©¿I¼ÖD~¦?v‰1OX75H":J(8H 6?"4598-;$59!9=%6K)'44*):,+0'3&=02D"+7,&+. !  !2*,0-/#& %#1;((0&/*$"$)$"$%$!!$#!*,!$!!*41%)G- ?+)/9!8%"*!0%(+&&(5!#1"$ "!'!!)$/')/'4%+1D:&E+3+(#+#)$( &4-7=6:7>3?B*)>#$/'*#$4#"/;$2HN5>PG&F7)*-%"0!%+")#+,(/B/?%%7'3,%2=1!8(%&-@3.OOFY,/E$.8,H73DX8AQ!BS&:M0;A8&9,$1& #+-"0%! "'''&*3!3,!-:)>9$/D' ++-#7F2!*.,-(+/7:3;,8&,<+5$$$#54!=:PA;DK(==#>V$MQ?-g5* 60 )2D8^‡Ul}HoƒE"C)#,'&PR1C.22!)) "2,#.(/'GD*>T'1A844?=G@DR8=J)CGNGFIuˆ‚jfˆZˆ‹5]l.NL8H.,'‡Oq¸ÂšÔŽK€“I^`?NEzv:7N$.Os*ˆÊH‹s*²ª]ÍÓqw³„§šV¡¸“_x¡£”І¯ut›•¤¥k~†Rs–sUpvxvЇ©|u§€p‘jSƒWaŠ6–Xk…g@WZ2mq@xK™iФ‚‘³o™¯[‚™hy¢dLj^MjMYmBLZ1IO0AVaz’¢²ÆÛËîÀÛém˜Zg†gzšIоP÷÷v•º|uzv‚ƒjzH1GE"34XD&6?)TN"gm!HH'3'3,7(>N=l…:]b1\_('9.!'!%#&##+13s†ZDX@„Š_‘´j‹¥Je{OŠ—9’¨Hf‡Tn‘Le‚j˜°_–¦?‰{Q¯uÂÀå¿Ül©Òo‡£oŠ«UŸÍP­È6~ˆ'`h)JXA_xTr€6YyV\}UpK€–=m|2Zn4Yj8>W27M;)GOAiWb‚ .8%%+"$*&-040;*7G&8D",4&,!1!!.5':,*9"#,&.996G64SAKgSRd\CihGoie’N`u7HW@WbQp„n¶³nÎÉ`«¶e³L‡?c]FI]ALcL`~B^oBVl6Nf6Qd/;I(?G08.:S=#%!-%%)!)!  +     +   +%#(!+"&"&%$#)'&&' .!#$ ##$#$$#! "$$""% . '*%)%'! '&&##,"%*#*+%++-0-0#;2#@6$h3)W@$W<)F6%@-!7(0'#*#'# %$ (/*0/%-0!1-#42',3,/,+--%0#.,/"/4$*6)32%2:"*7$'3#,-%8.4;/; 33 19"37'/8"16(23!48%3493%-7(01.1;9(7C)*;-@1 59#72#76$@6)78%:82@/8 0275:7"4E/.@-*0&/+/*4-7/1;+3#H0PP4&D6)+ 3< :D+5@$+= 79$\Y+XW"=?2E`6-N=IVFVm4Z_'2)$-1JdYeŽa(F,#$+'+ *)VOgU+-#"'.38U„€6av_t›kjŒ]o”MgƒR‰¤OTt=E[7JTNq†cyŠSe{Tx…jÄÖx¶ñ{Ãx{®fz›LGiU•g|¯hˆÁ_ÃíH•¤;q‰O—9dx@eJoX‡ªU„ŸJh…>B\3,@') **&6<+@1'6&)!!)2".;%4>&.%%/&&"*!&- + *&0#,$102O;A`:=V>AXOLsRo=Yo=>\RRx~‰¹––²Ž¡|ˆl|”PNbDOaAVgGGgPZr=SmEQj9Ro1DX-@X+GZ1DaA%&#'",!.#&! +  +   + ! " " *'&" %&$#$"'*#"#"%&%(#$""$"!" !&"%*#'"'!(%%%((#$)$)!)'-*(/!).#B/%^1#c9 LB'S6'A3$A(#8).&!+!) !() !$*$*+ )'#($!,#*'2)"6*0.1+)(&)!.)#/+ 1.#!0&0'#,,7/5>*:'+8$,2!-0 2-"3/$00+5 .-!,230#6-0927#-<19=.?;9@",8'04%4/.-#-0%4!$6"04-6*4&0)'5/$47!1-713;96":,'/.?+17$53 93390<0:&(2%','&' /(+3'/#)242 .//(0/4:.:531:::=E*=$214?B!EC2"$$  )#.'/": &.$+1.80C+1@--C)49+1?*>(G6T\*>c-3FE=9Q#4@!AQ2=L(EI"CP4C+@#+5 8/-;?%:!,4*,-5:9B>?+K-$1$#)-!#$ 5,A?HS'BL6/O-++07110(*2!*4>%5A()8*@2BN).?!(8+&3&"%% / 6=6>!-A&:&$$  ( 3,;40>+49!'3'!!%&*&'!$&%'0#4!#' .149<@&[S&Ib?HMHXVSlvNSj5GW3.S5^JLa5<%0@)07*J;$Vq<Œƒª…®y›^]›uTjqƒ‚«²•¦Â‘| i,Y""+%%%#&&%0/"c8–Žruƒkg€wXxg:CaJp‡L\M–„¨zŠ`·—Pmo_mŠŠ‰–®F”‹B® %G]gW)nw$dg?ôqŠÝ—e”©”µ£Ž°ž}¬§¹Á––Ä•‹‹t‹ `ƒªcЧcU}^i}L†ŽdŸ®P¼ÎMÀåVc¦•NzlбVrmPˆ“„ƒ±›«hZcX¦u9¬Ð`§Ð†ƒÃƒe‹‚Ž¡‰²ãÅÌcûÿ¹éÿ‰¼qt„R‘¥h‹¤nЧ™†“vFqtp¶ÿøŸèö®ÿÿÓÖ”¤H6H"-13J(+->8I-9 -;02=4-C&*1"N]-1:(:I#'&"(/ )4-{|D–«5y|48.3+HC,„…F—®d‡š:JX/(A)(""04.@ADb2'2'3 *..4jkE0I"& 0.4777*JLaišZ=Y(MQrj)•–?`†Rz‡It~T`yX`€PSoM]S~ŸF°ÞFËÜD¨´NmvLw|I•ªl~ºwPxZG^Qd‚a|ASi0JG8GH=]BTlDay@`i:ds4hyZlH&#&##$"%%$$%'    +! #  !$(# ! "$$!%!!#(0***#*$()$)+'(+&1'+'*#+#- &&$*'2'62S-!a6 G:08/.("7,#<,8&=/(+!)"**!%%$&'&-(-(*)**0(0+ +)#.&",)1*+)&$"#!#%&'%-(1.$15(-,(/.0*/)5+"-1!-+ 2+5/5,!22/3 0,&3("-+%+(".(**,*,,$4&4+0,#).(+2(28+#:741!/(%5**.&. /*!7*$0+#-)1( 8.!24"4/!4*#*2 6%<-2+2./-.*+0,03-*5+0-23-"251=+=%98-5D-28120?):886F36J IC$@Y:C? 0&-2?'?@+,>'),)/ 07%.<#<5&+C+)7*;;#9D .S2(@?4@)2H6'HA47<:?0)C25<1+J5+;66@.;E'4K'2C=0A>)?#928P-<>>/E&'(%!+ 0/E>HP(4I9)8<:<->I'4@.4'3*08(6$*2)79(@A+7D8/;6 ,#"!   + ("&0,&)*%/$).'1%""+$K6LU[[2IT-1@.#.%+.6,"/"#' &"0)#)$*"07" $0,-+,-4<=gZM;`B8N75T[XBCCb>EF09B0LDW<^.3:'DW+S?,KiQzbh•“|j…uKif1Ufbb?•q]Š›€Ÿ¢u’f?V5:"!)8)iX'}U€›}sŠ@‰“IK}D4?'MB(ch*pGQd\@WRt@]kD|yep—j}pqÿàŒ¨ÇLˆ…Ro¢k{Ÿcg’ŽoŠWr[Oq“HX™§ nµÈ…š¦‰¬Ç‡•â}жq_Œ^?UE?PI†veŽ£`˜°¡Ï•r±M&8)ugV×Õl³´Y”˜q‡£xVˆWƒœÑ䞎͉vsbS^HVWl‘d›°‘òÿÖuˆ™‰‚^¿ÓjÐyŽp_€\nƒ¨Ít€Ž;©±zçÿÿ±à¼½Õ¶ªuSiJN['5<5N*/44#"&!+02:,8N+L^"%US%2C29 -1(EGm«¿€¤º_Œœ&LE$dT£Â€§Ãƒi”S.,7>=A-5).*1B'*./1$/?N+OXL{ˆ&HP!@Fcd82!-.(VW/>KE8OQLaMW„J\mhp‘Z\uKM{]gxM`vI~‹E|?«ºX²Ý]‹¢ºås¥Éf¨ÁU¦±HXtTBQA6H*-:2>VIhI\~.E^Fi>j€HoŠ[i‰_@bRMqRMmSm—^r•bz›g¡e†¨Khw:?+/%CS>I$GV+Sh&M[6A%-$-,76?&+?!/;/u„"JNEN$$)!/!/, !1&-<#0?'CR5McB^tIvŠ[k‰dm‹Vg{JOfADW=EL79=/8=),2/(72/@EKiPf~I`tFXsOPlBH_CAZG*-.&.($'(%$&$  ("  + ) % +&) & $'& %"!!% /$0)*4-11.3403"04-5*2!%3(,),$,''((+4#F*\/Q?:8*,4')* ,/ )!!5!17))#.  "$1!2(0'%"&$"-&.+.*)++(''!-(.'),0%**+%2(+%% &,+&"."$1%*%,%&'*)*% /(6+/01,2+ *&,&5)7)60 8+;0 @-8480 00"0&2)(*(#-,31&54$6+.4-'/(0/1( .)4"4,0*!5(3+60<+5.1**%+")'+! .(0+2+7*<-7689 5; 15!/5"39'48"<7%?H%&.502%/584;/28#4896AT)8P,/=0=C"3D&8,.(4>?)5S,8B+'?55&"+ )$(.#!9G(A50:,:7&HE$AY#/I$+F5-:2':2(2)&5#%-3/-.>5(@?'78+.%)'! +),&19-3>-3M?&/1(1#8-AB'@C-:F!8801"'%-$/='48&2;6-63D>TI+=938$&3&,&!?A-=?GK.D'4,)7&2/-!,# 4;/;K-5R-3>4,DaM'C&&&.,/*C?0:&9F:UR4=_H1GN4Mp%>k&4'@12AKp~ePk‚Siqh{1iw!0.)!D1“m-¦¥Gª¸`šµph`PœzwˆÅQam9ƒ^D¨Ù\¯n­Å=v±)Œ˜G¤ÔTˆ´k¯¹mßM§±²»ÐˆŠwo€`X{o}eKfuZPŽ£D˜7ŠÈm•—€ª|u˜€zšyu‹y€Q 2¯£8z©i„r^Žw?j_Òâk­Ï€ÿé»òÿq¯Às4fw/NtIn[ADNbzŵkÿüŸçÿÄ¥ÇOx~4E_CFC5D*3>IV*CU"+-:398,=+3'HH(7?$-F5-1%=E'2>&"-:}iƒñð‡µÃg5}…z½Ð—ªÅŒ{™ENM-).C1EIG[N^vOFeGHrLi€J`vUµÎv¦ÊkÇûˆ´åh©Ìef‚yšÈs¦ÇØùR—+GT%5B ),),/H\Fž2\{:Hb>7R=9YC-F66O05L.4JA8UN7XVJobOwadŒdZz:9U+8L#5E).!+C8K^,7S=Dc4:  1 7!* - + (# #%!*!+ *"2$0#,&&"(!  $#'(%+',(,..-,4/109!35$5=!9@!:@)7C$->%-6 -5/0'1+5&- *!)I#?:7C%-9.%.&-#& $3(.-! * & %((!5&<%G/K4.8#,/+0 )( -,0.*2 /&0.-.*,1+02,0 20-+1+-*&'*&(&$(*(0(/) )',)1%(&*$)* *+"1).20+4,1*1,#+)#2.!*%#-#$3&#-)$5'$6'3++$,'$!")&!0".,$., /'/)!-+0+9*:/!,*!2)-'3$).(($)' 6)2/*++&=).66-7,6/"52$+3#4,042160/5/5"34)92);:(?8<4B4O< ?D$8;6D<'(?#!.1* @KDW:W29OBEH',? <35>@HLZ/O#7>')7(2*05).7 &= 56&/<38741><,0.+8('.!/( 03-39*/?,*0+$0#$%  & RDEZ!DM0BP3CG;JJ1GX5>U9(%"/+!+/%' -0,+6).;&)7"/0B5"L'BO+>G(+5'/2-6<;==71>' 1"#"!5F)Pd2[hE{F_sNKZN9N?CM>M_BUq@WjF!5/&&2,*4/)-#!.;#2=!*Up*m3'n:.c90G:185 1 W T +/(! 1 +, '& -"1&-.)%&'/*,+&, +*/)($**,-/.-,-,.3/6-0 /3'1#-.!7369 7<%7?*0C&2H%=E)4I+A?1HG16Q*8?.;@'?E!;E%4G%1<"=?#=D#?K(GQ,;A.@I5MK!C^=//' (  >4 1DB>C/>P7AM7AE5G=@#,/F$!'>+>?H@,I .844;=$:BEK/#J96*&EG?0@/%06. ($9'/.G>;g,8">AAG6M,efW`…L=„GeO9CxZglR>f!. !+)"3&  +G+(0*#"$$*+9:=H9-3E*2B %!"P"£©ÃX¬¢r®·’”¦‘b‰Œ~¤vx†mddji:LimgiPo5l–=Rˆ>J^YprAZx@hoLU‚ˆd‹–¥’¦¼’o¯tV†~„Ÿ™„¬ˆ„¡–usnw™kXhX†€ƒTŒ¯ynM:_CIRF_ƒu=kyAW`L]EXcH|ˆ?1;#$"*F83”¯K¡¸gT}nÄ2‘§Má½ÿÿœæÿÀèÿ¡çó¿Ùÿ’’ªwžß”mgLm˜€6yK"ȵ ¬Œ›1D,28mcw˜\€Ÿ¯ZSm;T04B&<82:/5 &)6$3584"PH%CS&'8:@QPS{Aw•IhNZ‡šÅ|ƒ¥^›–N`sGPVZe…¤Šw–jBY@9H?5=,KS!ST6>&2>9(:,56+<8=H[57E*DS(V]$]W(y‚.uŒ6RuAh‚AyŠRw€Sp{:GR).3%6=*GQ45DB?]H5G11=&(8,/44>>@Y5Wn$:G)[]6;.;!7A"'*1@/:%+2@"8K(Qa7ZwNVŠW[}GXe7L\#".%*=6JY:bl4Se*LH#BJ'HY*AK'('  ( &'/@>S|]‡¡w˯Wul:9C+C8BLDMM+@A-E<','$0&0743/8%@K)2;!#0+(;0!>2$53'*4'"&"*! -).--/+5)+(!-)$$,") &##(#/'0.10/.27+6#&0-(.-8*!89&N96r:/DK.N25>=#97%B9".5!+/"08!,9)24%45"-3!+.2+4./01215$22722/.,/213 0/0127!181472!/113151//1+4.1!/0(,-)*$@.1 %$&!)"0'1*1(/)0)!1%.$ ($ 0&/&!5*!0,#*$,%%$#(#!+'#,()%+*.')()%'&!+.#1)2,#:-%7/!6/7/!D,#=4!9- :-%4*B*>9"91'4351541.$;1"57)62(94'67:K+AI<6C)*>#57(1@.8@$:G#@G#@O16M24C)?F.BQ-?Q79Q4EM-JP,EP)GQ+:N+@9+;1>&=<'=9*[T-Ih;?L<5U1,:>*:,B+2I9,073"0B%2+$@0&T^%j" ¶*‚·Hv7RVbCSj(9KFL!1G.%4+dX2fd@J\17TP6EC50"+K"+%$ #)(',66"<905 13'yT%>k@Š’=”·nš©z¦¶„š¤Š¦£oš¾UcŠ]]]_peK_yPP=-;…HY`7@TA7BIabLdqd}‹G‡še‹“4Œ’K€¼s~‡…”n™>™®tƒ¨’…Îgš±T‡ªjQZ²ºžtÏ||viŽ•L‹–(‹†78E5Y[& À'”°8m—0DYXj‡g”›Q»ßƒck?ƒjyÿãÔÏ䚟ӞwšÌÓf¶Èh¦ªm_‚Mš’?\Ž$1~:>Ve„VVw2[p)>R56D3-8Z]|NJV*I\%0> )<23:=*K“£K”¬bZ{@EW9[nQ`Š\‹°Xd~=Pf-;J!4?1979'FD/9H1;@4CIDVgt[ˆt>]14@!/=,@0A+9:M0=Q(6B2F!IX8@X9FW7J`>_q$Sb(DO"GM7>";F8@OZ1Zt/Ka48N;,$28!33,=!)4%D,'O8)N72h1.aI-k@2`N,?G4:5(5:"7<%:72< /7'40!)65632!7327$01!3/"62#03$99$4;"65%4: 8;#9>#9>)6B(8;#/=#7:%58"6?&4<"1;'4<$4A'6>(5;'<9/5&;5$9/(;0!<4%:1$63 --1'2/26 >:)=/$B7!95!60$92'+3+2+%[0<:"19#E<)9;+7=/6<'E?'DL+MM4=Q)A@)JK&BO21F09:+7G0DA2RG+E\+>W7HF(=F'I>?E5F'3)&.!1046(0*($/"'!# +!  +    G9@I$(S7$C   (0) 88<9%33'2?(,%+,+`Is{-u•KS†HTqhg~na†mi’RP}=0J8C@ER"?U GYC\1WncHaI)=#%7%- %"   &%)$# +-1&4>'/< ,0ESJHJ~ƒ>ˆX‰€Tˆ…xž²”­‡¢¸—\¯ 5OMB=Bry@€ƒ>nŒ+rw5q€LSk;DV#D\Fdk[s’m]…_q|lƒy›¨‚¤Àe†¨lwpj„ˆ…RŠ—^snXY\s‚ƒ>¨šr¤˜n¿Ït¸Ñ‹¤Æ‡§Ìˆ†ž0dhZ$I/!3+>A.‰vS‹¥{™ÂÌ»wÿÿ]ÿÿFÞÿfðŠQ†”QqLÅl·Ð¡˜¸’y‹``hIÞ»–Éôr„ŠåëŠÊõt¨n!(3-.&)++C=L&#.,2=!7J"7M!;C!76<&:D89I5:H)9B!,-.84A5A'BS41E#@O9L,Wf>Sc7Yh8VfAfyDjz8Ua.Q^.Vd)K\.Wb2c}B`yASk)?O"8F&>T<&&,*%4/,8*AA    $>6FDGW6EO*:@6GTP‘KŒ}5QN0859R7HV1T`EUd=SZ):3!(4)8H5GS3BK+9B'1;8>N9 +    + + + ' .0 'D Q ;!1%!41!.4$--!518377%7316!14"5,88#29&:1(660:'-1(40!77":7(59"-3'.-3127 .2!/5!4/%3*-1*2!4.24!(@"$6#$,3,.7/:#36'35 3-!36/;"0:")8&,. 341<-=">2!B?!8:'<=%4A,0B(5>'7E+9;':7#=<$X4"H7'J83R=6NB=JF?L<7\>/ID(B?/8A+32%95%6>%?=&::$=;%D:';@)>2&:7$;7);>&;;%<;)8:%E='GF)?D+6B,7='><&@H*>H%=F(4C*69#<:'98&9=,24*7:$.<)68)7>!9@$19 7=5B#9?#4I%:=#6;%6;!/=$66"-8 5:"4?'1?,.5 .4 .806"/9&36 46'2:!75$31&72 63"/)!6(6- 2*-(%1(6'';'"=3&=0(?3%<2':2$60$=,&<3>6 ?2H0!50+)!:+3?,?2#AE=; 8;B<H=*:B"?5J@#DJ'4A(36';7(9?%CA4>H)3M1=8+EB'AD):M,EH'>R+GJ4NL1AX*UJ0L[+HY7EX)GP$KH#R?'ER/GB-;C%17.<4)=AEC+>A%>J)7L.=?8=K40<+%5 $%$''"%#"    " ' *2       &52;>->;+%L("5/-#'0&)-=~\Pc¡[PmFF`3sW4Bv7 .;:4+MP]i$Tv(;X'5G%;I#Na/Le85O$4/'.!2*  &! #78)06.,7("+;8'cz@‰Šhq‘w†•GŒ§]¦¦µÇz“¢ŽvqKad+ed=X|scxЇ„}‰di†p†¤FT|Œ;­W}Rm”nkp­µÿÿ<ˆ—CTnJbN_]5ƒª>jKjb’ƒ6Vx7EAKPDÒÙÌÍ‹sŠg’¼²Ä֒ΰV;S #+65411*.YVIe&;I'>L!?AHM$bX49N&-+%&*.$%>:SmA‡“N]fGzj@µvÁäuµÍG…Œv¨¸r™uGuGkt=Nj3_j^„¤p|œIQlXK{[Y€Ž³’¯Í–¦2Q]5”‹Tƒ›L•.>S+-1%?920DC2HBWy†mo’H\p4x>Wl:\pIi…OtŠHƒ£IªÅ?µ¼>šª6cq+V[*ON IL%9B?DO1DC$FK"DJ,`^.?K&443;H;7G:0=*0(-#(+13:$>C NKC>55$IB<^S6ZU-MH8]RZVlp[n@CP'56(8K3XYNx|h¾Ÿ=c`3CL-3.=LDIY=;H.2:,,40/@7,/$'  +  +  # 0;*'.M d L*D*$G0#@1#=/!@3<9 B5%I7#:D#==(A0$?5&C7'H9($.<(71#55#19%3;"6B&4C(H; U<)I@3DC0>'<=)?>)><'G5#R@ XE,P>8L9*L:6G>5]<3NN.SN>HB06=3;<(C>#PB+==&?@(M7)D;#D7,;:(C;/?;(==,GE+N=-K=+>F+A=)D<(>=07?(:<);F+;A.??+>B,;3-?<%@?*>J)A?()93'B:"@A&99(81#:3$0>)/<(05$34#-9"<1#;7 :8(@>%4F%8>$7>&2(4>$0B"38%3>$6C'4@$-6)87 6>#<=&8<%79#44&.+%80*=/)87'76(E- CC$D:#73'80(:/%9;+81!<,45$;5(>:":@%=8%>5%49$<8#FBU"=>gIƒ‡™œDƒœc|”dwckœaalkj kŠ‘žl¥šb‚¥WHaA8bWMhve‚ŽMkUzg‚…±_`nE9hRSh:R‚\;LL4NB6P.;LH(9ZUo Wq"o&ED"ŠŽ=Ru/8I+8G1o~?ª´Gž7|†#\e#J`C88B!5E<‘zZ²ËfØú©¬†—£ºÎ–޲lˆ£[g–ccƒ:PqM~‚>s’wMŠ_9[TKV7Gp;Kdiš¾Ÿ°ß«Ìß‹ýÿƒïÿ“®Ul„L:E"C><2"4/CF&9>=bpO“PUk18;0TdRs™[}¦Ya~mˆ¬Mdt08C@=1M1CR5Yq8Q^2Pd-JV0DN$GX,Qg/ht2Yp8`t2hv2mm,Se;Hb9JV*GP3O\:[hGZhJ_yOcƒTi‡JYsLcvQv„]x’Y\m:NeE(:G4:?3?N.BT4QNolUEQ€d€ZVi;9H,4H2=L?5G67G+-4!-0$"3.r=,o?&d9'l)q)s.w,r.u.v.t0y/„: ~<%|7'‰2•5”?&€>2…F3„D*C2†I,N5‘G4‰H3‡V8ŠI@‰D/D*I.K5xQ3TI8NB-BE&:B.9?':@%&8>'6<'9< ==&>3'N:FD"?D'D%GI)CK,D9*H7,GD3'@B(>D-A=2:8(::,?:)A:(P5$@E'9B%;?&>E)BC,I:/?A/F9)A<"BK,E?,FE+;>-@5,?B'@L)AC2DD,BM)CC/=G*DE3<6*>@&BC,CN,GC+>O'H=*>C%6D)7A 2:#<=#7:!:;%:A)4;.3B*47,9A'"CH$AF$H(G/EK(=O.CL'DQ1>K/;A)7:+A@/K>.FG*V9)cP*LT2CJ%>A%<>%:<$EC-AB'MK&LX&J]0`J>Oc9=I2QR4Tf-D]7FR7EX7JU:RQ;ZU(?T&88F/JWNIGT8P3&B"*,$#/!!+#' '),)1#(##(!1(" +   +  0-67"JD*??+(B" ""W1b^NY+&D$#8(45.hfY_“ACX0]\:Wy5‘“5vTm4N+Yb(D]KRZhŒ•Cžªs«°eØÏvޝg}‚:ƒ.;J†–9R~ao7db4lo7VYIiiJ_kGew\‚•N‡“U†CjqJlrRgtOgt1Vf5Qg=M]?TlR`zTbzVPeapu]]pZ…šKsLnuEnk0LQ>ET5CE05C3XW);H9Sm:^j2MY9GJ5bX.NS-TV>GO9<µUAºX@º\D¾`D¶^E®\I¼XJ°XE®YG²NA­R@©UH¤SL¬PH®WJ¾TJ¡[N®^O¯ZM«RN¥MQ¤KQ¤KF§JD¦QD¨MJ¢WN’RS†MImH?RJ>:E7>H0@D*N)DM'H42H-9?'E=+JK2NG0HN4CJ8CG3?L3AK/@F.AE-BC.@3@G*=G-:@'8A*H?%BM3;P2=B*=G(>I'I=*@Q,:81;H&BD.?J&EG2BJ0=I-GI,@Z/H+@G*HD6?K4HG,?U+F+4B.>>'D21=-'0+@5'>=#@:&FD);N*>A39B!BG"BG)=O$7@+:@+1B#8;$-=#5;#6?%;B&=M'>J#R%=L.FP7DN+=N0BH6GT/GT.KX)_S,Tc1Ra)YZ0ZW3UN/ZA(]H$IT)DP0DF&LP)=N1PT3Oa8\UAZ`9Pc4fc>N_:U_:TS1Da.b[>]mH]uCip2bu4Rp5F]:;ND:M7EH'Dj9>A9=5A?2GCA" =(- '$ "4$61/2 '''.+$,3-018EO:4".3-KE&8C+(;'B9,t_…}u’ANzMN(9QENj3lƒ#IpE=V@R]F?_4Pn3AO$=RSc(Vg8i~=Tq-TV+Q`&ED<="+0($7 "3OFSTP_sb)‰®Iy`W¨6it;mJ0•–6’²`kŽp^}jPO8m_S_nEgjJLgqs†}hšSv[Qo™a@SCHI7RqE/E.;FXKhCOoKEuQFW[CX@9QŒ/s|/by[*Nnƒzu𽓵”‹Ïè}¦¾gt˜6j†[t‘DwˆHJj<\_,|‹=„œ)~”7‰¨Mg,CkKAF:T[cD]SOC3ª XøúCº×-.:3>GRw„`ÆÚw¨ÌgŸ®L“¯XQŽ(qQ Œž9‰—QŠ¡Oœ¸dn›Q`{Dp”Y’¥VŸ«W”×¢\„‚hxt^‹öÆ–×Ôs×à~©Ægi„k„”\|§Aêq½ÏaÓÏ3´ÀA}›BVc7LU;f‡[¤ˆŸ¹¥¬Ó‹«Êœ¼³šËƺöËâ[ªºU‰¢S™‹Iކ@o|?\ue]ƒ]MODipPoŠDS^8NZ>FSVdIGSL[qYzŸnO‰Ÿ;hxCjwAuIŽC€€AnyOz„GuWua’™dŒ˜Z— SJ…„S‡’Dsx;Zn4N\6K`HTnCZtG_qK^kENaUn’hƒ˜W‹R€xO~yUo|SmxJspIxyQ|‚IuƒAls8aifa=V\8QY+UN#BH0JU5JR4H@(WK2dj2DR9C_LTl@GZ:ER3:I/5I?Rb/DA,ML;}w:as/DT'@C#24(8<,=C,>D$/1#/6']:M]=I]9K`6Kg@CkANa?Vk@RcARfCWjD^e?[j:[d>K_;Wm9Jb=Kb>Kb;W]4Bb:Lb9Nc>Pf>G2:E/8H,9I2AF*@M1>F(:@,=G(CB)AD->L/8F0/E.;<*5D!5B+M.?G+BG0BK/BO2GG0RN+BP.N/CJ1GM.?J7?K0?J'BG&MN2MS1FU8AQ6AJ/DM)FM.=O7AJ.AN.CL/>Q)8N,EI)>O.CK4IA9BP.IM3BT*EK,?M+6K-:*DH)?T1FF1DS*>X/LL-IT,?T1BJ.>F)B>$EF(EQ+@J,EX+>R(>A*DQ,OuCccKuvE\vILb*Wf&\ˆ/]l@gg&qp?T}=`^,7_5&7&)**",-&@29J79"9>)0C$-=+7 017M+;<"%@1-6F387?F/FR*92+$.)(IQ"ae={Š`\€`”ŒFxž-b”FHk?GX4JX%O\"qo+br8\{.Jt1*T3IF0^c!X`-bb&Wx2:T1hY8Wf(t_(sq%Wj2~o(WfOBW\Nd%G`B7P@7A.>M8Z]cj\m”Z¢¹vŒÒ`ˆ§jÂq{žJ|ŠY„¯Qž°Vt¬YOŠMFdHWddJqr4OTPXVVwBLg@HXP-<:@-#6%JC&g€4X=DH8=R./F5+Ea'8J%3/(:(K;F@M]3?J-3/7IZ!MR%uwU\wzKaISU4ueN•¶uC„v4=I*D>,L!8@[kGp·ÇŠÑé ÃÞŠ·Ýc|ŠE‰­R_‘fmt<‹‡WHp~Wj‰wz‘†™Ÿ‰¬‚k‚Pt€I^9=D4n|P¡Ê¶ªÚáh¤’RNRa7Uyƒ“¨q}–Ÿ|…¦z¦¬B_ƒ[EZU_jY~žKv]˜¶Iy~WgDb}Ee~F[nD^{W`oy›o‰’m’”Z|}Tr€WqvS…†Y‰]ƒ†Vs~S‚Pr|Kw}KuvI`e=^bAig6e]9EJ1@S/STBXY7RT5CPSk}T`p9Xc=Xe$68&)0(/9->F" ' %3%>"5@!/< 2@#4=&0:"6<;C6= 9>!>B$:=!I09O1@F+=Q*7I09C1M+U7@J1?K2BI1?O.GM6FK3CN0KJ/F\.FK:AK7AU2>M0?R1FP4;M1=G0?R/GK+NR2JV1OZU,3L35E2=@(J*=I+=I,KL%FG.DN-G?1JE4;J2:D2=S,8H/:K,7I,>J+BL-?V,;T0?N-U4GS7DW8CZ1LT3A^4ES.NS-GK)AL'=K#DD$1H%9=$?G'=I(M)1N/8D"3A($>'%2*%1!.1O? CT)7G&)*(/E9=+9@<>K+=C MO!DT2QC?ŒqQYo3FVJdKTh„Neu8kk+YŒ/w„3]˜BhiW(XI|®/œ£O™ŸO•X{¢‘j}Š­—8†{4HzSYu\vrŒ‘,F@,ƒ—^7hFE^CCO-Fc2G^"_yE?T>IN7hq4=`;#B"DF"'5M?%as:Cd8JM9WZ9dj5Tmgb5o„DY\h‘Kto&^m=KbXQ_e:W5+3"02&E,.`UEr Qvœ‰¬Å“‘Åf®Ç_’¦E˜–OÁËxy‹P\nZF]_G^g1MdCR`RYIj^R–5d]?j^g„z|—¡VÉà`RU.pr:‹¥vn[›’]Ÿ¥nØîy¤ÌW`~4v‰LP`F¤´]ÀlezSi‡="7=$59&A6";=#C8)A>%?G(CR/GQ0DK1EM3LK2EV.;I4EI-AM,BN+=P3=N46H/BJ*HK&JR+CW5HM5DP0=R1CW9GW:GN3EU4@Q0AG0=Q2AK2FR-HU6OS1FQ8GH7>P9@P:EM/IV1A]1?Q:9I09G-9D+>O2CV0VT4Hj;9R7H@+BS'AP.5J.AF-K//M->D4BL+DN:FX1BS0DP99P0P)7I,9A)D=&.I*5=1>J-7F3:K,G8FJ5JX1DV6AU-FT.CW1CY#DN(DN&DV+PR'LY7BU/A_.LP-O\8JV-Ea2OO4L`BSb;He;NN1YV;Yo*ak5TW8[Z0QT3GN1PY9NO6PTVjQQ]>hcJd{TˆqE_vL\oUZ`NeuX`rU``VXp8LV<7X&6: ASC:>$JG-NL.F^#8?*DqUDK-HC(=;-6[59646B3IN<]Žc257NEJ¡ÂZR¿L4V)8hG,@T61Jj†n&Q=(8&#."*@27QjH^vLg„Y…˜Jse(GM2LX-PM;G^8@J34H36H76C79D+1/9 16!#/. F9'9<%A3(8=%(5-# 1 ? +4?46&+,+ 3Gw"€/Z>0E3:###  +  + ' E IAEM$>M*?H3BI*?G,E?)EK)GI1AS0JP5PP-HO5IS/L^1OR8HP4FP0?V2?Q8DI5CM,OQ-NV,SX7;^8DL=;N+?F.EO4GT4KQ4EX7IP3DR1AT1EJ/ET-DT7NO7UO4PY6FV7EM6IR,CU4:P/:@55A&9<+@A(@H&LS/ST->^6CO<;J'9G,@O-7K,A@)FL-BR4@Q0;O0DQ7>W48X8AJ4KO7PV0Ha4B]5=U8MQ3I^2HW5DU/ES-F[6=X4AN0?Q.>I)=S77P*8F-=K-GQ.I/?D'Ld6Sh8EP/J^3.T,-5_<$a{ORmMbxM\vFss>s“Jjy7KYJ\cQmˆRvsNg”;—”6£¸O°Eh™Xb|YkuBhh1K ­c_“ke„OeƒLoŠ[[v|x‹{~˜ToŒc?n@^}[Db4TL-]];;d-@N/.G):A(9E6SH`EV%?6)^‹¨2DM'! !,(9R,').;( &+#5'!.""*@_~}‹a{~:PS_m4`{S„ƒŸp••Jjyz\=I&@R6Vf5AQE7;BikC{q:Š­J›¦lºÊ‰Óæ•‘Æwy˜‚?Z~~Š“U{Q=bW63!VS%wu/¤ºm®Ö´©à½:x­9h©"Bj*:vG\|Sgƒu‰²œ_p|n¨ÁŒ¡Ã|’­›rž¸©‘œÁC3G_MNz—KAJWcta…‘Jhƒv^v—g§m‰‚Xƒ:_3Zg>€’;qŠR‘©|ºÍ‹Š²yÂa†¤c‰Wz£J–¨O–ªs–¡^˜¬q’¡a¯¼`¦²K\|7EL7›œG·°K˜š_œ§cµ°c§¨]˜ _´¨YªœZ œa’™n žs¢—j¨Œ[¨Y˜ŠRˆ™U†’O‡–gŽŸl—«Vn~T|Y€–€€£ƒž¨Z¥§fŸ k¬·dšcŒ±c€¤LrMw„M}’N}~;fxGkxX‡RŒWŠžc€i‡˜^tSp”Jk‰hp–{ qrxq‚–vº¯d’ ]‰€NuyRk}Rq~Qiv`Š’gˆœo‰œl‡–l…Ÿeyˆ[vƒTvySjsS[q^i‹pžn„™^o{Mkv<\gKbjV\st{‹g]pD|{>]jAT]@&~T,bJ 25 ).60+99*89+0C,%7-$  3 +7"94!>:2C4.80*9/ C o })"W@5O1EE7MK+SY.S`/J[4M_I#NL%U\&Xc.Pd8Qb8Lc7JR6IU*@O1FO)/W,E>+>V*GK3MW3TV/F]6HQ1AQ7DK(IN0MN2=a9MQ4BS/@P-QT+Gd9MP0F\.O]1Pc5Bb8AO5BH(ER'FM,GR#@Y%=S+AP+=O+6L(K?*F['EV0LU3T`5B[4IW0O`2Cc5HZ:N^1B`9EV,KZ,JS4MP)CZ*FX.JN.FX1EZ3OV7I`6HY0CX/?F(GM/GP-AR.AL28L'8>$>M)BK/:U/=O17G+AB*7F%DF)CX.9O1CL-IO18W4=K.@L&7N46D/=G+;H+/D!>A+6<-7I-S/HD/AM,0A.5C.DK2E\==Q5AO1@U8>P;A[??JMS.OY;Od9Jh7T\CIcBQN4SeLCP/LX?W]3Th?al^^DloCZmHRW=\oQu~IoˆSn>`q*Na>cgRmyD{šPip\xBgy2s:O‘?GKL[bJiƒO^h:{r6ƒ‘KeQo€P{–^v…„‹ˆƒ…¨n]FkqYl•It™rbˆ‹j}^|‚Rg˜bh›nSUŠœhS[ˆOOORi+NgJp{:}K(1%2JI&+$-4325K=CF&:&6<* /8I1I.1SPJ3qID†•-@_T?T=ViNkj;GQ(AC5Spa¦¶²ÔÿŠ¿êXkwBpm=We-`_?œ‘s±³«È†¬·uŸ¤=Tg3XpO[rXpŒuezw]~V¡¡\‡²c{°P­±P£¿½Ý“ùÿwÌÞ{ˆ¡YX|½txœF£ BŽ£w˜®|¨Ãl·Á~±¼~£¾p›»m¯»w·²q›¤e”žb¥Ÿ^™ŽW—”_‰]‰ˆY„X—¯k¢¼s ±©Ñ{½Ò`›§V•ž\ˆ“d‹©u­t’®opq{™`zŒo˜­]žVŠ—`œ°X€“SŠ™R‚še›¨l—®n¢j|‘em}]w„YtŽZqTnŽls–nv{`syo‚œ{©fŒ›Tx„Ny…RvEu‡\ˆœf…—a{Œo‰›j’¢gz•Z—V}Ix{Ej{Us’mv¥m~ d}Xf|RjoK`lDk}]RgS6KWn|ZfoPoy:U`=L[>O\0F=!,2 +2'>1/?6'I1;H1I@/IN.IP5PX7GW;PT8NJ7GG8KG3OO1yT.˜]2pw>HlAES@LMC\>QQ9UZ4UV5LW7PK4MP-MH3PU=FP0E@0`E,ŒR-]f=I^DAU3WH-ab0Xb:MbHKZ@GX8HX6TM2JP1IN.BR4PK(>I1HL2MS4VX8NlV1YO/OuBF_5TX0Sl;Ob4R_2V]:Wl0T^3N`3R]2T]?We7KbPc-Pc3Qb9Xh6Ff4Q\5_c*Rk'Ja4P_1Md+QY5H[(>O.DN(QU4Gi0S^/Qd-Uf5Wg0Rc,Kb/Hb.:G'??&DJ)AL"BR*>R'BS)GV(BU18L.:G+AI':S01N2DC/;[3?P+?N&AQ#MR2PV/D_3@N/FO(BX-LW,MZ.KY6HT6?M9HW5CYDPW8K^9O\3Kb4WgOZ=UU:e]7nkTjmM€tSuj=qŠAt…I~}iy–SjHq„Nl€Rg(*-&( #&[J/4<)gbA^€cXw\BT)hrV?> PU4zoQgAVb3K[Gtvb¦ÊnqšmTNƒ›66<%(A5,£˜j³Çˆ‡°’¯+6E/&@A:7C= [d5haZOZ,89#cgU”–’¸„‰©mI{rA`~TnThQe€1Rs(=Od=YgclWMl]?>M,V_>‡oŠ]™†DPf‘~XÒÌvÄÉ>vwQ‹„gOWl^~˜Npž]zbƒ™Iwƒ9\d?YrCbmNd{[‹™Wh~K»¸_ž¯‹›½‡Òÿ¶éÿ´ßÿ„ˆ¨KXhH„•Tl¡~¨Ë’³Âg­h™¶n˜©w¬µz¢Àx¬ºn¨­u­£nŸ f™¯b•§iž±g˜ªe™MsˆM†•rÂÖ•¢Ó’§Ã‰¤Ç®Ôÿœ¾Ýmšhˆ›lv–ltŽlޏbŠ[„¢U“g†®o”Âf—Ÿd‘`¢cŠ«c«p¡¾xŒ¬pvŽ\x‘V|ŒJgmJd~Uq‘Sn•c‚ŸewŒ[€Œ_y‹f˜¦g«e‡œR„˜\—±b‘ªl‹¸žÀ]‡œeŽšcm…dƒ™hŽ«a™°W‡˜Gt„Xzš]kŠ_\yd{†WsvYRhN[xHmwKVi8NYQyh\t~Kmi;W_(5?*.?2 5,  +< @+ F<&@C3EA2A>3=62A-/V!"o' Q5/7.@0'.*/'(   6 <0<>EA/AG/J<4=M4@C;EI.=I3;?,>C0E>/DN/JS5YQ6OX:TXEMS6MT9ZR:NU1yS=ra8UmFR?QT1Na:G^;RS;JP9MQ:NX5I^?VS;aS3\m5Ud=R[8PQ9ZM2^d3Ya@N^ELQ5PK-LQ.NLFIQKFM6HL1XW1WS=N[DE^:5R7BD/PM(CX1TO1W_2TX2NM1NP,WW0TW.G^:GT3=W1Mi@L`&Ca<^S;Uv8VnAF`=OZ2cm7SrBMc9Ma<;U7HN5K_GLYJi;bX5\x4SpDTgCUw4Xg8Og8OZ1Oe4dhDi:T}<]dDRy:Fj@XZ6If.B^,TL-H],JO*HV-SW2Pc7J]-CZ'SW-Ob(HT.GX$?W*=S.=P&FM&DZ&DG7HY9NV.GY-GU,FZ/J_D_q;Li:FT5XZ4fk=Gw;[\;Ek1MX:O_>Zi>UlE_gEKnAU]^C~y=Nv=] 5|   /)'\`N$SMJ2B;NQLpFDp!':", *" / dV=R!6@ GBEU9FUOq~rh=e ioˆoft@{ˆ9‰‚dh‰4iy)ys=Ç윎Γy…j ¤Q~£,s’ 9›§F§¹AHEm|8Nb4Qd;YmM}ŸKS:WS6PcAR[DNY;QT6Q\5V_<[cEObDNYAUS6a_8UZ8ZW9Ne2FX=MT2Q^/MaAEZ=?X8IM*OX&Ja6PZ2Di4X]9^\8Ng4F\9OU3Ob6NW6MZ,DY,AS#JO&K\(KZ0La9Ud9Fk7GW:L^5^d9Ru.Kb?Q\*Re2Od;Jd5TY:V]5Mm7Yc=XgCWg8Pc3Nc;X^2Yk=cqFWq7^i;Zn9MmAQiGThFHn6emBQyEShFRj?Wl6jh/kzNyD[V@Y_>QHIi>OcBVb;Wo6QkB\m>Wf=`o5[v:Qj>hp7[ueTER1BV+CM/DR;XvWg@lŒebŒgWn\y’sxžq¦kb~IWkN:XpXzˆƒ›˜Š˜—ƒ’“—ª”¹¿±Èx¡µŒ¹Ü±Àγ¸Ê«ª¿…ÀÅvª·k²ºuš»q–ªl©°y–¬sˆ¦i‡¥`€¯jƒ¢|hš›…®‡®|}£_}¡t¤¼ˆ«ÄuŸ®j}¦`|œm¡··Ñ¿Îw›¯y”³y½sŸ¹²Ës…ªay‹RjOZpKlvK„ƒR‚‰Xˆ—_„”UƒŽfuŽkx–e‚£kŒ©ž¬†ˆ·nuUm…]v—w“©lz¤d¨fŠf†Ÿo‡£tx›i}–[‚U€>ht5_lRu™i”¹_z†\KQ^@RWVf{]djY`gCmh2ENIi„O^sKs’WyŒh”°^‰™P“Y{ŠSmƒQ9C.:F+2E'E*"+ " <BC>J.N8>G68J%>@$KA BQ;K)?L+>G,?H/EJ1a>DY2GY-EZ;GSQ_<]h=[v7Xr@Vq=Wo@eeJ`@Xg7Gu>gZ=`z4FfFKQ0PU0Lf2G^;UbA^s?vj=[y>Wj@]oGZoD^g?dvKZ{AcmOW|BY^>|f2N—?TTcƒ;i„FbzFYkJan2Zs7[p?Ui7_q8.XdM;ZN>3zR2Z&DB&Pg"Tm3\uIq€/nz*w5sb„£}Žžy¹É|d†C_rSCOVpfK\}Nfxe„¨n…›MXm,alCq““FH8amL„X‘¼hi’jXkIsoH¶Ây¸Ø…®ÁcÎ傪ቀ¯N‚¢Qai>afDbwNnz>pAOh<+M\:Lh=KU5DQ5UjRx–aŠŽJ|8Š{6µT7^S}šW„¥c¬Qš¢Em€0IU,gqPŒªl¤¤c‘§R‹¦‚Ûç•Åà…Çٸϓ²Æ’æÆ‘ºÂ°¿¤Ð斸еé¢ÕðxÅä•Ájˆ£h¦Yj|\{‹j…š`jˆ`oŒiazau•iŽ t˜Œ–¾~–¶SŠ¢dŒ©‹ˆ‰®p‚y¯ˆ{ ‡«}‡£}t“]~–Vw’EsCvˆR‡¤Y™YŒ `Š¥[›XƒMVsd’q—ªw”±t•¯eƒ¨SwŠOl‰l{šRx™\…±l„§o µeŒ¡_t“ak‡Uf{bi–\Š¥S‘–\}Ÿw}¨rj†UYtLFR9QSJ^nL^`JhyLƒHh|\‹›Uj{`‚fov§y’›Zw‹\tˆUj~P;C/=H07E-=&!!. B<@GC,DN,BM/AH)>H'E=(D) B""; 6)B)#LG%DL2EM2EJ*LI+QJ%EP,MM-RW,VU,IO/HK2KJ-QR/LR+EW6MN1IQ.XU3N`4dX5nZ4Y\>SZCSV:JX9UOAXW6`a0X`AR`>RaCLf?QUAHd@LYF\S3K_9UV=Ha2HU?DU8TS*Nc+NY5U[2H`.G\9AW2QT+I]3WY/\_3Ne7S^9KfL\8Ka2C`9X\*Rj6GcA\^:Ey4Nb7Sd4JcBJe4Le9DgKI]`m7[uCi{>Vs5Qv7YkCVrORpG\j4l{4T~Kbk:ZqBqr9v1NzJ[Y"f{A^„LWvBan2gq7lu7T|5^p>or>fCdyDWq?am:Sq@Xt=aƒQ]uAnmH`‚DTx?esYQxBa[?eiouA_ˆ7bgBd~ERk?Wi?SmFZs9Vg=Nn9\k9Tƒ:nl>eŠ2he9x¡Eg‰Iv}Ea‹?m‰W\~7bsCp‹IVr?a{JYyRq„O|‚P‚¢^†¤‚wž]‘žZ¥´lw]s²^w‘Vq¤jt˜cg‘zl“lw•dƒ«y™¬w±zˆ©oŸµr–¼ƒ•¶w—Éi‡Çd °q¬¼w”Óž›¾pšÅÀ” ¨{—Ç— ¿t–¤`›®~˜¶hƒ `‰ c°o—°e›È[‘´Fy‘0[p$¼3uœ#‘¹E€¯Ju}/r„/Km*R|T1S-/;/8L 7D&EJ0y†Nª¹]›¥[ެP’ j}«}’º\zŽv‹¶_v=o†\m~c“wdY–¦z³Ð‘¾Á†¦Í‹Ðêz¿ñ¨Ål‘Âz‘¬ˆª›’°rx©¢§à£—Ê€€´u›Ð‡éÛcawSis†¡cx—Zm‘Sc‰Wh„[pa_|nzšwƒ“\m™p}­jv‹ky˜l†šlz—akˆ_qŒZW{WcuPg[lŽW€•Tw˜\–¼k›»oœ¸g…²b{—mŽ©Km€Qv‘a‡¤rˆ¦ƒ Åy’¾exˆHczc˜NeˆWp—lx¤t…¬e i‡§k‘Rn‰Phn~Ÿo…§c€˜p{euFF_9AV9HJE`o>O]L^~ayŠT]wt~©[m‰Y\‡ckn}žtoˆZgXpˆ]qŠL9?.@A.4C%>+$8 D*9C=?,DK,DO,BI/DO.CE-?)#6 0 . J GMEO*JM2KK/RR*VM.US2WX8`S;_U;OU8RN3US3\^=T`=Mc@YT>McV^;R_;RXBV]<\]D]U=T];ZMAP`4^Y2ZfV^CHZ:OR3NZ;R^R[5P`9Ka/NX.I`,IR3Oa1Ib5J^5Kc1VY0^d.Qi6Vb6Mf=J_?Ia6Cc;DT4IS+P_/J]4A[.IS.QU.A]0>U+LR*E].I_6Ye:WlBKj@G`=L\1Oe7F_8Ld0LW5Kb'fe4F7Ac9H\5M^1Ee8I[6Y`1@aN{FVx?^xLYz=zn=aŽ?Vo>d/e=Q‰O`p2Vv?roARLYqNV€HWlBvKu’Mv‰:c“RQwQcnj|9f€GXgIb{MUsNLc:Yj1]uw=i›Ey’LjšSpsHX†KcvQ\}KOvFpˆTt–S|‰X‚‹Jr˜LtCqM^DXg>ay@c‹6cr9k„4s5\‡:fy=mˆ7Y|:htLu˜Z`“eXyRbsISuP_k8y€S_ŒDcsXy‡Ps˜Bn’?aˆD‚Ah”cnZr–Rƒ¤^†–o–k{—TlBw‰Ml‘YlŠL_zGu’S£iˆ¤gxµtf‡_}•p}£o~§|…is­s˜ g¡Çt›ç‹ŒÀl‡ºyˆ½ˆŸ³‡­¾n¨ÂgµÓt»çu³g áS‚ÉZ›®‰¤lš›k…Ôs…ƒc†ŠYv£Y|œV¤®^›Å€…·m’´ck‹MwM±¥<”š*”À3‹º:|”/’½>–(‡œ.OW-UC`w)‰‰$ˆ )k Qh‡?q˜XT}^Ž£Q]’L|’P„œ]“¯OºÐ;i‹hD`U‰uaeœlHSmj†=BK'l~Y‡‰;¥µS™ÉUÛÅY¡ÝMˆ¤Sœ½aˆ˜^œ»sa‰_VleŠ¢CÒ²fœÿx†¿mSkEUZ,S]%@™ÄL¨g’¡M‹·d]yCYƒI^„7gu<]ƒ,mq>ŽY“µv›OtœR]†^pœW‡¥g‡¬jH_CŸ¬^pte‰ZOp&3: fu=l‡ykŽRt=c‹Tvr¯Ò‹¢Ä‹·ÒŸwªwNsHO\X¬¸|½ßxÇâŽÈᇾڈ¡¾•„™t©wœ¨]¢±w³]‚˜]z‰Q‚šm¦Á€®Ã¦Ào•Åx…´fr£KhHgrQpXY€EBgPVzjZ]}šl§º£€ ulzCYqTe~ck„Tk€Tz’Sd‘T_€L\y[h‡c`ƒPax`n•`t’Yreq‡dpŽRe}I_€De{=cvFdzNz…\†³bƒ¬_ˆ­t‰¯r¶h²i‰¢az•Xp’[ƒ¥cƒ«n‘¢z‡¹…´nkKgz^oRe…Nq”iƒ–`l“nˆ«w“´kl€P^zRk–n„¢v˜±g‰^jƒUWp;T`;R_4KLGuHr„Eq‚W[|EIZhsŠhŠˆB_wR^ucj‚[m‰Uh•hx’mƒ W:B)E>'.?()..$#)<@ELK)BI2LB.QH0IK0WP4TO7XJ@]M;TM=RM?LV7ISAITHaGWANT8]_=aZ?QWCLNMa7HZ4LU2I]1KV3H[/LX2R]+S]8Lb5^Y=Ym=OfWsGesA`€TYŒJNrQ]v?vw3ƒH^šG^~9I|G_fF^ƒD_}DTu?SsD_tB_‚Bb‡Zd{:r‰Eg†?h?j}HeƒQ^{A‚ˆI‰–A€¢?]•AUpEbn<_}:k€?W†DWtWl–tCw‹HŠÄjd†6{…[¨±~›Ö`˜ŸaoˆŒ‘²su”Q–Êp_‡Rr‹ssBz•M›Ä•q—¤vˆTTwB:L/BR=Le4T`{ƒÄv’¦U€¨k^†Tr|J:ZD‚˜\}¬Oƒ¡]¨^°Ïj«Ç‚vV~¡Nt•;OcNavZYlNMiF]qwpŠIKjauAk„OsO„¤b¼Ë~ƒ˜¨´ãd„;-5)-* - + ?% F7"*;.+3/8+$?5#2:+>4,<%#&#7H6O=$NH*KF1N9.LB4\@5pH._I;^LP0EL1FO/GP;>R7?L;:I2TI+rT-hW6YT?OY:LVNc?Tc1P_2Ohcz@UƒD\}\{Gbt?V?byR[}=[y=o|Fk‹Vvˆ`|Ab”B\r=ax3t†Gm„H_„N_‡CUE)JB);O)@N0BT5HS.WV(R`5Ti6PgQi=^rAT{R]mHewU2JX0Sf3VlAlsM\€P\wGc~GW€K\{G\€Pav>^t:S:cyAa€8axCZvBdu@[qJtyGg˜;r‚RaŽGh‚AU†LwsHƒ—H} Xqac€M_}@XoDVu<]w?mzBPqH[p?VyMmpWmCcrKNŽ?WiQNl6Im@RpGawRU‚NPsCaoGeqLe‡@[}<\w=fy>a…LŠ@z¢Kg¥M\ˆAQz@SrDpwBd–>gŠKb€F‡GЏ]d>d…Uf‰Rk|?hŒSe“Ib‚JZˆ;„wBhŒBw†Ha†2{}Fƒ‡H}®Po£IjŠKe–NjvP^y;l}8zIe•Ot…He‚Nn|Cw°MsœTtšV~š\lŸRt”]„¢FžXz°]’­]„Ç]¤\w•LŒ¬f~«sФN‡ºSx¤@‡¢Py¬Up£VŒ¡Yy¹P|·YгYš³Zp°Oz“ZwSz¡GGm1v[vš_{˜U­joŽTq‡Li€Gf~Bk†Gr˜Bn„]¡Àr‚‰W•€Ž«oƒŸsu”€y–i–°p«Çm¢½jmkTuz—j˜»rbƒs½¿ÆÛùކžf fe}\†›OŒ™@•š@‡›Flˆ;\sQYmgSYVGVLuK\†UnWo‚slƒhdw=LR3GS6HP;BI8?N-9B7ayE\q'JX7ZmS¾¿ˆÿÿîÿÿÅãíX‚šO|“Vs]wžrªÓ{½xŒ¿š³‡ž¹”§±etŽhtXzˆYqƒt„¢Œžµix˜QcˆY]}Rj~DfvHh‡Je„S`tQSjCKk?Kh?_xCl™Ry ‰±†wkv’a”imŒa[jHQZ1FT6Tc8JT'5A:WkV\yfl‹[r~Tg}T^pHTmJiF]r@ZjGe…Mm}@`uKOpAFaI#&#) +   $",$2$%$)5.97$4;,0;+6:&;9'I:'_H*RG]p]l?Iu4Wa8Ae-FW0Na,Fb;_]8as.dtGTKJtQPiBRc3Li6Ijvz@]J^v9imt‡ax lV LZqBi„4Ls6QqE\sBYFzJb£pWSb};\‡OVA^~Nc“F[‡=n‚F_Ž@v~S†SŒ¤Gz±N{žMŠ«fÀ\bŠQz‹Jc—9cu=[zC…Rz¢^jˆAˆ—Et“Fh‰Nb–JjŠIc†Q`Ž]w„Eu•ov˜ZoTc¢S}«cn•L{Q…›W}•Yšbu¦e~–[—O|¶Vv˜M~•Vu—xS«Îrz¨M‡»n|ŽX‰­Y´SoœD{|]q¯MzFy¥T{ša…IqHz¨@‹¯b„•DšL“·?pŒL†“I ÐK€¤D€—R‡¡^m§ac¯\Œ™P˜¥PŒµP¥V¾[›³g…˜Z~¯V‘»l¬w†¯rq«Uo‘Fvšf|Š]‘£St³[’±]”¬f|¥jq~§V{¨P~®l £w…—•†°vneŸ|œÒh|°†Ž¸aªS¡»u³Õ|…Åz¤Ãk­Å– è±Å“¡åv¬Òs“¯r¤³l˜ QÂF·e¡ÅŠœÒuÅka“a¢‹K£Rt—[|€qµÚnŸ«nŒºv›±vÊ‚“°‘†«n§Èk‹¨m½Êk£Åd¿ÙŠ¾â¹ºî“Çøuàÿ¡­íp¡À|¸ÄzÒáv°á‚°¬d²Înž¸u­Rcm‡u‡c«Ô‚¾Vtr6†‹NupWµ·Kƒ…Eœ@Œ¦}–’jlp\ÁÁ~}–tx™Ct{Ed}dYo…‰ˆaµksrµÊr†e}Ÿh^†°i`oVg‚j~e½aUiOlG”«pq^y‰NU‰:\‚N`}aš]gJVh8E\ICXG_o-Zx^|£b†£tsžc…¯`z“Y™Gb„AfSvšfˆšYthžV©³ušÍ€‚ª^‰šVp•c™s”¸ÀºÜ‡«Jg€Qm†z¥Yu†níðÏÛô•§WZuV\jN€”]Tqmr‚]atV~‰P°žNnx5Zr4upEWo[XoH\kEG]@BO@Uf=P]5R^;|}3S^1Pi5hq/?YU…™Zìçg±µg“§²“µÿÿÿô·ÉÎÒ{ÿßb £Z…¢]ˆªl{ c{‘khƒzy”ŸŽµq~‘Xd{Qi|Vk€edƒgt˜k€œNl…HKd@GcH\pDKcLdzDmt;Qh9_p9`l>UpLc•w•´—³dx›Nf’Yt˜VoŠHm~Afu6U`5Ic2JX.CL<\qL`z_v^lwN_hJZi=TcMe}MhƒGk…@d„YnQd}CUn=Kb=     !+ 3#"# ",2(.401$.3&6/$0:=5!Z6#];*V<8DE1DA2E8#J?+R?'HY+BO9IF.HC%HI$NF1VK+GI,EE1GH)MM-@P(CM.QN-G]2LR8JX0MQ2L]3FS4@S*=R0EN(GT'MY1JZ.G[0\T1Le8JW:BQ2PO)Q[/Mb5J`*Hb/D]4FZ.W^0N^0Xe7Vh3Sd6YZ5Bp0K^=La2Pe1J`)Vc.gl:JŽNOnJPg:Sg9Up>Qt?\o@Yz8PqTtGXkFbpGq{;VŽ<_rC_z:WyXm=]m;i|DSAYl>`…8On=Zt>cvDawHmZ”^‚¨Qy˜Oc‚LmQ~ˆMf–aY…:_tu–K|¨ejbgŒ;x˜bm•|m›KmŠXXn:\†Nj‹LDhGH]@d‡Fo†5eŒ/NgAHcE\sJ‘µl„®L^€g…¤j Óu€¾KmœRz°k—Çz†¼f€¸ršÀvq©r—·hk’Zj‘T†·w§™Œ´¨¾g˜½^b€Sm‹d~³r_™ËZ’vQkYw¡>dRwTb|:?TCbkF[dhˆ£„Õì†ÜðqÃÆRV`=>TCJaA*BC&@C,EG,PH6@W*E@0=I)AD/BP,>E0H>.YI+QJ2HK3Um6Xj7Wv?mwC`‡ht@[‰CfwH\‡:L=Yl9]}?j‰Mm`o†Xb†Id}Gm|J_ˆDRtO(3G#7K,HYGNe@P`8UnH_zJ[{Nks—½[c…V•k§SUnI_wEB^6@V3Rc=]j6S]0QW:Ti8F`Nd‡nxŠIvKfvO_rC]ZIObO]uLg„;Rm;8OYGvs€ ~        #.!$& ""&&(&$'&(,,*./3:5 E>&2K>/?D*9G-@C*IB,=U0>=/=F)@J0AM/@G,LG-TK-ST6GU29N6GC0JS/JV:OO.LT1MW2MX3T[-TS3QX0Yc;Ke:E`;PY4RZ+Rb;Fb?S]2Od3Z\0Mn3[`8`r7Vrf?p}G‰@t—@\VdvMg|Ep‰Gj‰D`ˆJm{FTŽPauUkuGf…Tˆ…L„ªZu—bm‹FmŽGpRmGˆ˜Hi›WaƒHn„;c†yOa†H[DW‹6k{Kn’;r`mš@J†°J}©Gd‘=l‡@i‹C’Ph¢Kc€Cd~GYƒDg{G]>eu=c‡;jA]{=~z2q¦le‰9v‰Gd’F[ŠNsuAcŒEv‡C‹Fl“Dn‰Jy5ˆžOe±8gƒJR5PgJZvNkŠTˆ¤Tv=ci?V{BWpOvj†?_ŠYcMpzFuˆGdšFT_rtJm“;wX}…;~š=n•XnŽH\ŽY]ZW‡Rf|RrŽFr‘U{šS`¡gn~BhŒB^…\o‚I€›?r¨Mq˜\‚˜W{ \u­^u—q\”hj…\{—F„¯G‚°ap[_‚IfzNi}B|TWOanFeŠ@bzs­BeŠ@€‘ÁeŒ¬s~¨wh‘N_}HfBt“QjœK|‰Ai–GhŒ5dB^†=މF¯S’‚L|¬ti¢ViˆBsƒB•¬L‹¡M†•Az¤V…ŽS´b—œC‰›SލI˜F•ÈEu”‚vKlWŠ›}²ÂsˆÌ{¸f Á½y¹Å¥ Sžºe®JtœL‚¨mšŒ5x²[›·V}ªT€™M’²k¶LzÅc‡²Mw’BŒ«ku‘JŸ¯QwšV™Y€±aw’I}®w|še}­Y©^†¡[‰¨OjªWޱXw¤VvšOw³„¥b~¬\­çztŸgbˆCn•Ge’H|•C›¯b{£S€ŸjqžWh‘k“¢[v™\z¤Ws’G{¥`y¦Y}žf†®U|™Wz˜_¢±g•©m«qˆ»V–Àƒ¡¼|†¬m‘ºgœÇrª¯Äo×étš°iŽÎ~˜«e‚²Zq‘IWt>yB•ŸO”¢LÈÁQ™Êƒ‘赫Œ»„¥c†©\£Áf»ÑŒ¶Øœ³Ü«—ªn½ñZНaŠ[ºV˜¹^“Á¥Ú¡ÐšÁ…Ûþc¼úh¤ÅM´Ûp»à_Ùð[¥ÂDÄÍD¤ºJ ¼h„¨Cq?c:b}@sžU•µ^¢ÆdÐìg‡¿P‰©e‚§]nfz˜Iv›[q m\‡„ƒ°gkŸOoDcƒJoR‰µuˆ®ki‰F%GD'9K#9G,HC)MG(ML/QR2UE4UT1TV;M[;IT9YY1d^:wlC_gAzf>ZŠ>HiGO[Xs:[lAih6et>g€?p„NX|LW{\auPMy]WhCcpPX}Gct@TpB^i;\n?^{BT|A[o>TuCWqHU|P_tLMp@Vr>RpHMq2Xq@YzF]I@~HRh@ZsCgtC]‰B`UT‡;Ov@Bc<\d3i}9yŽ>y¡BrŸJl˜P[‡CekHf…Dd”So‡\ˆ˜H€Un¤ec¢^[ŒSiS]ŠQY|JSz@hs>wL\’CyŽPWSŠxWr¦Fk•Ms‹H\“Hw…Mu•W{˜RˆK„¦ap³\‚˜Vz¢Sb–G†‹L|¦em•bˆ—\~°\€ J‚œFƒ¥Eg˜_[|:f†An…LyŸDpNt„J€˜=p±[|™Ab’Fk†CeŽ\‹Obu@`zBd„|9z›>”ªCŒ¯]‹¬F›‘Vz­GeŒ>ŽŽ@§W•ÇfvšJƒ•T€¨O‹®]u·e~še¥_œc©¸n‚ªLÌ<„œ@ Îb£©r‰Ëk’¢[Œºwg„GwŠXš®j½†ž®P}ÍP£”M‹º^~—VÂ\¡G–E|£d™œWžS¬F–Z~£I½êpt£J€Gx¥_ŽœVƒ¯W|L~•OšA‰ŸV…¦Qf“HwŽS‹›Qw¢Nm†I…P¥ÃdW…v|ŽFš¹Jv¥Uj‚DeŒHn•r„ŽO–Fm¨H¤Gtš`nSi”L…šLk¡Pi“OtŽKt¢\qŠL|£R„©hu•[v™I€¤X‘º~£Å’Š·m•·l˜ÁuÊk—½z}»¦’Ás™È}ƒ¸“ƒ£o¢ÏRƒ¤?¨¯^ŸÄ€šÜŠ¬Æ§”ËÀ¶i±ÿyžÈuÄêb‘¿‰ÆoÄŒ¯ã—Â|Âꘋχ~§j•Ån˜½Y Ír›ÊZ¤§j±Ðl•Ñv—½~œ…—»ŠœÐŒ¶‚®™“Ë­»ëž¿Éƒ©Í†±bŸÁT¡·W˜·^ÃÌjÿÿxªé¨ÜŸÀ\Œ¹fŸÇ}¥×X}¨[§Th—QбH‚¥Zv¡Pu™Qu”R{©`f…^jŒZn€R^…Xp ck›8Qo3Jk6^{?[sO…«_hŽcg“`¥h£¬GrSjŽTX~Il’a~§mƒ¸Š¼yw˜Vp•Qx›\z˜Pk“Ei‰Gj•Ph„DXzYl—Vl–]w¡u‚«l¨Ç_¨Vy—St›K\€Kk‹Tw‘Ne‘T^DLr;n“SeˆTg‰QbƒYi‡UhƒgŽc„ˆ[wŠg–j—šµ£i†‘g‚Šu€ˆmNj\n~Tw…XttXewVn–Yi†Uh†A\sQv¡Ž ¶`„›EcuJSZ4NY0EYNRz° ÜáÍûÎÏñ¦Àù¢ÂॳÉencn™ilŽB{¢L† Np’\xPRgCNgEBW9KeKQtTkKYjRyMmvAPk\WzPYf0NfKTo€ % - %!"! "+ 6 3'4'0$*"% %*$%#$$'#)&$!'%(2-+8"%5"4+75#=9%8;,7@+>A%>?":B&>K-BF1E@)VK-OW/LT:QR2VS6US1O`:EX?RV0]X3i`;_mEhgHXzI]iPck8dl6cg;Rj9NgDKfAO\9]_\=vv@lFa…Q]rA]rEUx?OpKei1Z~=[t6dy:XAQxIHnKTl7ak0bAP„J\sMZyAZzA\i|¢Xv–Mh›R_‚ay€Kl’Yt]mŠTcŠMfuEnŠA[Ž[t^˜js“U‹’I}Ágšc—±[—¸z€Æi™·] ÅvrÊr„Ž\ެcbµw|‡al;uEj“MxLz“KbNeyMbuC`x@~‰:s¢Yk“Rh‡T”‰A„´[–SÀ³I”ë“…œUv³aqŒy~œ\’›d§›¢Yp²šh—woŽSpŸu›YvˆKnŸPnHr›T{¤`•¯sмe…³q“¼bz¢ky¡e€¥d–¾h~«g™½Uu¥VŠ©_¢YŠÀƒ„ªd™Ôr‘¶w»Þi¤Þ––Ë‚ÃoµŒ¾b¬Ëm¡Í€±çŠ ÒšÌˆœÃdw”Vœ¼a™ÁZŠ©y“»„”°ˆ´€—Àf‹²€”¿j£Çf˜Åp‰«_ŸÉeŸÐz¬c–¬ˆ†«os–]–ºlÂÞa‚ªe’¯ƒ¾Œ³hg„`w™g{šSަlq”Xj—Tn‘P†©Q~˜WŽ®P”²S‡«O›\i’KiˆLqŒDm„@iDZzHoŽ<[„1>e0Fe9VoBg‹^f˜JlMŸfƒ«fޱSu—T°VŒ«Qzb¦\v‘\nO`ŽMi‰Lpž[‚ŸCy Mq“Ce‡@jŽDnœQm¤QY~Um‹l„ªb_ŠKw›OeEZ…Cp“Gh}BOx9Go4?e/OuFOyFYbh=Zu]++,163!.%(&'#)#0$>,61 0-!(&&# %+(+ &,*&,,&,..#04*=2,C&07&<7691B%/9'7;)6?#4=&@B/@'WK-\V,QU:SR9RR6]W1]_2Rj]dE\f=li8y{6i|@evALy=S\CLc4D\3XT3_c,Ul;Tj9Th7Uk8Vb2Yj9_xBWyGelHhx?n€D\€IZ{J`z=l~=]†KZv7[u.onDdˆEoJm†J`‹GqyA`KT†[bnKsvE^…@pvOi}3h{Fx|Fa‹GXrZkvD^„Cqu‚—Im–Ev‚PœœP¾Z€©d{§Z…›Ot¢yb‘bu‹Bq”Weˆ]_€Gg†Nizny’Chn{‚Dt”Uˆ£S‰¢_z©To”P}‡@ƒ“g–\ƒ`nŸY”{jˆ«{™±A]šŠ=h«Xžžr„˜t„Àet›až¤oœÀŽ‘ÂjŽ­}§±_hªPYˆQ^Oy„keVw}Eu‹I]­9o‚E­›Tj¨c“^o»N€¦L{`x‹Ov pvªxrŒM­J‚“Q^§N^nBf„QqGu‰9Š›dm¯ow’YŒ˜XzŸ]v¥UÉÆi²ÿvŸÊU|™PfœCxGˆ«Z…œU€¨d„¯K…«F¤´t—¤O„®Y‰—=p¤Ke”P’¢C‘ÍUyŽbŠ®[{¬\‡¡ixN‘ fyÃvŠ›Q±ÁA‹¸d‹±\”šN°¾_‡£Yr£M“R}“V~I¨mްb†™E‹­[‡´\u›Ož©L§½;šÇuzœaš^ˆž_|±?•Pƒ—P‰¿J{šK‡œHvKœ>… QsœVm“Im?Œ Kƒ»J€FŒŸRvRlŒT‹ŸDf‹Ou—Hx‹TsžO–¶y‰¨Tq¡Bl§>l‘Ah‹EŠ¢T|ŸB„©LvµUw\|¤RpSpšJ_ŠKlƒA¡ªTŒ®eªaw©_£c™·QŒ¯Z¤cˆ£dw±V~ªi|˜J~¦P~¤P|«^Œ¸h¿c‡®Wn¨g«f‰·t†¸f³oœÐv•¹r‰µu¡Ëƒ†¹lŽÈm‹¬s‘¬P¯ÖÈq°†šÑn‘Ær§åp§ØižÚY‰¾d~³qŽÇg«ey§fk›\n›_s¥€n•P¯b¬Õ~žËƒ‡µX¥_š¼l¬M’¶O·U¹Z}®T|Pe‘Ki’Qn“Nn’Vr›]i‰U{’Sy”Sp˜?p”I}£Nh‰Bn‰iŠHqœ=b0a„3n‘>\ƒCg>i‹RgŒVjšZsš\v§Ns›` ²KpŒNxLuŸJo”Gw™Pm™P|¥b‘¾aƒ©Re’JgR|«Z{¤Lk•KaŽ?k’Ro‘Zh†If‡G]ƒM^‚9S~?Fh4Df1Lo,Lf*Il4\x9b€:Wy:Hr8Qr;EgAEa3=S>\{XKtˆCIa@Ld_q‰Jb{HcvE_xMl‹Q\rJa{GYuHMr9av9SrBe‡Qn˜}•¾†½Ã`‡˜ir®t‡«w¡Ï‡~¤„x™beš“’³’‹Â‘™Áj‚©Vq^hhp‘]nŽP^y?WeJg€Kf}BY~]{”Ccv,D[6AaZ^€|†™x‡oŒ…>]eRhwmVu\`t=OlG.2$3$('0"1'6&1& :(97:1!,4)-"%'$%"#&(*##*&&3%11'9#(,$.#:2A> C? 9F&L8(OQ>L5;H2A>,<>";C(9?*9<&:>#@C'BE'BD%FF*NJ*PY0UU;\[:jW6md6cm0SsFYa[r:duGevFeyHhn=O|KT`?Xe3jo:^|D[j‘y@¨O‚œa€£VuŸYx‡K¤“Kª¯JŽ®qƒ¥TzˆTs¤Lu’pYšT†|`µ­RWÕvtmJt•Np„Nm”][‹T^zEh~:†ƒB‚žS†¤K„³dsžV{žrs¦e~ˆ^uD‹“Tw¤Oq™FrYl—^p[d”Ho‰?i•Qq‰\s‡]w>¿˜R¼ãO’×`ƒ•O{¤EuˆG{Cs—_£hf™~uŽJ‘œ[|ªH«‹PÛd­“AnÜkŒ^ƒL¦Sˆ¢Vz¡gz«w|‘fp˜Oš˜N¢²`©¼‚®Ëd‰ãbWRf‹aj‡^”‹S˜±gr¬‡q˜F`‹Ej‘K}œRlYkDt¡S}ž?qVp…U`ŒIf‚\¦]†Àe€›C›Ä^k¤Œ·`w½OxŸ^g›cz—F~™=y©FY]~9Rv7U{;\v5Qe+DX+H[8OuXfƒeužY†£@bwSl…N^}@Z†O§VsƒJi„EiyH[}?^sBjtH‰§wÖÚp›½„¤Ë®©º{‰¥Q~Tj‰sƒ¤zk—bq“[{ ƒ—Á–Æš Évz–Yj…O]ƒU_…_tŒV[{EarPj–O^„GR^[xGK[2B_;NiWh~wgzew}z~Ja\KS`J@S?-LELkJ1,3+..+1#5, ?-A7"G:&G=&AH)=9-79%<:"8@ 86 105+B2(E!87,J=IV9V3;<)C>QE H\,EB.WC0XN.NW0KO?(GD%TC#^T,K_3S[7^b2c^=tl?S€C[fP]eAVsAYm?_f9ep=Ty?_h?`q9_s=ZrGRwLduIa|WluJ_{Cr{Ht„D`{Ijh<\z>ze=s/lC]ˆJRG`lA]|EazNhtAyC~šMl™S\†YZp>€oŒ¥U€¨VS‰Ðak¤_{–M}ž@šQc‰W~™Ry˜Oq£Z|¢XxU«E…–E®Dz™PqžPl•QhˆEiŠMr‘O‰¥X…µ~iMt™MbŽ>mŒPeWu¤Sv˜Hl›Nš£Kw§g•ÈXkœgk†=m‘C\‡Ij‰LiP‚™gk‘D•®V€µHl›Rs—RrŠDs›StŒL€¥YxžJw ^vemFƒ“Tr˜eªm²R’°_z¥P„¡Lw£S’§k²Ë”ÿÿw~º\„­lr™[wœ\™·k­×vª×zŒ±[…¤^f›is¢[v¦ne’[q¬fv¨hwšUtšXj“^‚¬sd”ScˆIeMyQc’\e•Op–SiŒ^bŠMnŽNs“L^}<`}Ba‚IW~Sc‰LuŠWdŽH^…Je„I`Ie‚=\}Cl‰WgŽDfŠKhKc‹OyœKÙ¯Iw•IcJ^Da…IgI\Ke‚Gb‡Jt“EiOmXf”Mo™Gu‘V_†HhŒNkšUgWaŽJb‰?^…Ca|:\w=`|9]|Aa€C]|Amˆ:^{3c„Fd>Xv>Ur8Puk~3Vf6Vk6SgAeˆQhW_…Pd€SqŠLjˆBu›l«Äo|“Mx‹Kr{ByuCjrDtj²ßÌôÿ´ÌÙ›©‚UwX]ŠeвSpŠcl‹_yšf¬p¢É¨Ìò™žµup‘giWX†Gm˜]|¤d…§MZt@cFb‘6d;V…Uo€<)O>X?$xS*hk5bt>\uTnu˜Ip’V‡‹O¾¦>a¿eZyR{|MyŒ?t‰HoŒMl†Hk~?’Ce™po„C•‡Kk RrhBy€Ok’On„Mh’Zc†H•‹f„·hq¢mŠŠq¹¹UÑ[ƒ£Gt£eu‡So]™i˜Yy¥Mj—_}Šf­‰o·^v—X‹DŒ•>a˜PX;ƒˆ=rSwš\n”Pm‡X¢¨M|pp›Iƒ—@Ž«Z‘¼]§Y£œZpÁcw’rˆ¢\o¯>­’JŠ®UdR¡‰PÊ~¦²Z“ñ^‚¥`‰¨H‡»Mš¿Xxµ„†©Z»„n¸~}ŒW¨F€Ám£¨o„¡VAŒ¯^À«^õ[…ꀱŠy­R‰¤Wq¡VƒA’¡w€¥€nžMŒ]g‘P]EyˆEt¦a‘‹S‹›Mt¢Q‰–h’Rb—Wd‘Blƒ/l›?†§KwUhMe‹Fi|>s‘C{¢\Œ¨BŽUžËon£L}“?Z—Nf€>X‚M}Ad…Kq‰Ii‹G~›iw©[{¢NxœLx”>¿è½¬·i‘ùRy‘N†ºRl’@‹Re£]n‡Sk‹R‰š^…¶ƒ‹7w°wÀFˆ¨€y›Gg©‚s}nœLrGp¡S„™au¢R†V‚‘Ré;©Ó>¼âVn¡QšgwƒY™cy”Mƒ³I{œEˆ©Oj‘EA˜ºki”GŠ•C{¬Et’L‰Ÿ^xµ_q›\k’?w”Tc˜S…”E…§Gz¬Z{¦KnFu¥UzEr¤bm˜]qœRm•Af”<‚›=„¹Bg’Gh}=iPf„HfƒCp’DyHg‘>p=›ÎQ|£Vu¡Pƒ¨eƒ¨Oqav§H‚?~¢Cª:v„Hy°HnLnN_ƒE_…Ut—No—OšU’±O}›Pw’^€žLœRw§OyœJl’ZwžZy c|¤gu¢U‰¬Qp¢br˜Mƒ³b¥w›µ¶‰ÁZv›R„¬U‘²Op™^…°wx§]u˜ZhD^ˆ8q†Gn‡G†¨Zt¢NhŽFj’L|¡SpŸJ\‚LlEYAr…NužXa€>eŽHlJc‚=]}?qC†›K[|1q‚@c~@¤©L¿ÔJj†Ls—=]†8a†Em—B—@rŒDq”FeŠ=[~?c†?a~Gh‹?g‚I_‰AX~:Pz9[7^„:[‡?]ˆ@\€FVJ_…Bf„Db‡Kp˜Ta‘Hf=Y{KcŒK[†GrŽQn‘Di‹J`~>c>^†?\}>X:b~Jp‹Ec…9c‚>Xr9Vt2Ai.Mr1Qt4Uo-Uq5Y~EnˆFwF{†AyƒCr”Ip‹Et…KhƒKgzG_xCh†t‡ži“]““U˜’S›J†ŒP”´”µè̬罻ܒ£Ki€8`ŒXb‹EHvEL|NX‰l`‰‡zª®–Ìšˆ«Qc€K[xOcƒWf”}š¼°Vg@ay;\ƒ?Y„H\~Vd‰Il‰R_ƒfi”w€¢oq…Q^nCEF6=C:HS7DWL`v^iu_bG%fN.jn6UsGT]C[`;W_TlH`T@lY,hc8_pDafDd_6ci3hsDeijf>`kGXZBNV3fO+mX-v]0}s;i‹JetT^rEjp@a€OaqRPh<]dB[s=o[9lv>o{Vu…JTŽKTpKRlcq;rDs„Jj„Hc‡JUyHVaIld:Sw@hq[f}@S{BblBexFe}KX„K]sGeqD\†I^€O`}Mi€Bˆ~@j–UmxMquAyyHazAf}EqvMonHˆO]€VZm<[l6U]7Ra.Qh+jl2W:YlBdp@fk5Vr3bn=_4J{OYl;_6q}Am•DeWZP[s;h|3bŽ4b„@g€=‚†?išIpŽN‚~X[¤Kg‡g|>s‡8yMdŽM{€\t–GS‚VjsF\ŒJwƒHh—Uo€[€‰Ao‹Sp‚L•C¦žQ™¸Fp¯Oy˜krœgŽQ|¾i˜­ªig¼m„ˆUˆ£E‚¨Yr©ck_n”K’ŒA¡¸f‡Âk‹°WŒ½g¶´_}Á`pGY™5ovHZ~QrJf’Tz˜Rb„‰…WÀf‡_oŸ]z‚g}ŒZw‘r] Wm…DcˆZ€yMdœŒnˆažœ.nªs‚Œow³‘q m³\¦Á_~Ãt`°‡b‚[ŽT¦}¥£I±n^²rNtW_‹ªpu©hžb‡W½Ÿ˜ÒXĹUš¾[|°WvˆOˆ”Qœ¸T}Çc’œK½Q‰¤G‚£Rz›V¢°KŸ×S˜«YÝpqŽg…–VY£I‚3b=Y|9‘Vj“^oŸgu”Kw«Pz¶6¬]€§K…®I‹´J‚ªo~š[u›@ˆ¡Bw¥>i|6gˆ<\ŠLq…;aŒTg™H|ŒPˆ£_r¢[y˜H¥›©en´“uKd„]„”D·Qz¦WqBzœG^‰Zf‚\o;v˜U¿¤Zk“kYWt‚7œZ“®Hy¬jƒ ]ÙØV­ÍIø×Pƒš_r¶sg£‡Rj¦O_>t‰Hp˜Jo˜_‹Kz™f„ŸKƒ­Y®d|ÄL†£L|—a~¤Ll‘M‘¯^o’Ri“Cz£Nx Kp‰Lw•Mx“Pu Si‡CcŒV`†KiˆNl8iRd?g>f“Hh‰U}žLb@—NzŒBl;m“GfFi›FoŽ?k—nx—VqŽWiœlhUšTq§cj’Qw£X}§Lc†Ly‰WA™©KdŽ>dŠB… Ci¬[œ«_›ÌVy§Xz§[y§TmŒW]ŠNe‹NnCdƒLu M~—T‡¯Xv®T|—Fx›U{™S U„©lÂÝnx¡Nƒ¦[½Xp–IzªUЬPpšFƒžA™>i‰I~—K‰ e}¨ZŠÅI|¨JpšV†¦Wx’E„§Po:y‚L|…S’J€›ErD;cu9{‹Iƒ•Ll‚?o€LC‚ÀÿÿÊš»Dn‘RoŽ?uŒ[E[};a…=dƒAz—^\5f\9id;mc?e^@UeDXd;Me9S\4WY-W`?YY5]e9`qEaaHeg>ai:yfCozD]tEfb>`l:_kFn`@rmCmm:YrHdjCml7oh8oi8eg:auERLddRVsCbmDdtFVuRRj?[lBVt9lf@fv?l{Ox}L]†P]uRee:Ym9\u>\q<]pBMm@Vl=Zj8it@f†YbwUhp=hy4ZzB\uIVv@Zn>uplx@i–Jf“XŽQhD_ŠO`ŒGj€Kk‚Ws€M~–Lz Px™V`WjyLY‹F‹x<ˆ¦Hv RuUz‚X “H¨Q˰bÅñ‘ÐžŠ¦\’›Q€K ’_†¼]ƒ³OdŸq{Li˜T|ƒYŸ‰YÌP…´V{¡G~§bš¥ny°ƒd¤f““]q·x`’f}AŽ•Lz©HgsOQ„;n~F…[—F™R“¨f}ª[iUyŒG†I~¦Ue–6W§Olo0dŒIs€Fw¬Z›ª‚¿_“g\¢Jv~>ª¸_w§}`”fw†ed¦Hš€d®Þk‡Àzy¯_~š@œ”[~¿X‡¢[k›Q•‡[€Å[zq}šiz–t’]ޤFw¶eˆŠN¾cvªnu¬p‡œ\–µX’¤RªI†©ˆs·^—ŸZ€¬T~—Zh™Zw€9gIR€9u>‹­I“½G‚˜v™bй]u©Iq¤Ršil¹c„—T’ŽMw§WbˆYoƒ^{ŒFk‡GŸFj”6—œDmLˆž;„£Rš£Ho Fj…0~MgŽRp‡Gm©F|’Cy–]qˆQqŸQo¡LpŠMx;t•Dh“Er…K™[t£AlžM~›P†žn…¶m­W‚’S|¡|~K¢ŽQt’^o‹FbŒOgCm…Uo¯L}˜:§KÝ­F¬ÿIŸOs§Nx™Nz–WÂÂep¢Zw“[‰ÉcgŸJ‰¨VšC{¥Eœ¯Y‡®]rS—¼>oŒFl”Ow‚=iŽ@o@gCe7j”Fq-\€Cz˜Li‹>ƒŒHr‘?h‘L|ŒMxœ?zKm‰Ex›BtšLsEq¤Ap–Hd…4_‰AgPn£El…Fp—[j JR}6l‡@g?sOhŽBfŒG`‚]o™Ru–lc•dƒ¦@oFz‰Hh‡>p‰Hf‘9zU‚ž@v¢Crd|”Q‚¥_‡žUs˜Q}¡U™¦kx˜Tˆ¯’Âby°xpšm~¦G­c†´ZŒÇJe’]v¡^’­S˜Çqöÿ›×o‘Ám˜¼\œËt”°n‹W|‘n†¥T›²Z¹Yž¥^š¡S˜«Rƒ\–H˜^¾§h«¨IŒwBzpGjÇÀÿÿÿp‹ŽW…Q‹U‹JœMš˜R„Oˆ˜Eq†7`z>|‰=ŠžIHt”Js:y‹=p…AvŒ=o‹?g?nŒA_‰N™³Hš`}¨llŠ<[|3^„DdBo>a7V‚>g’Nm„Aj‘Cn”Ba†a?T‚AX†7[8j„3b‡6d~9_{3\~=_€?lƒDm‹>|‹EoCdƒH{ŠFy„@…T—¥cš–WšPU’ªqÄÉd—©`‰œ[ޤ\²ÅwËÕm®Æ{žÆƒ“Å‹šÉ‡‘²b˜>U{/Hg1M:PUq/Gj=`iDZoNYvOQsIo‰Re„JEdMFdHSn:E_DMgBi‹M|˜H}’?j+Ok7FhJaˆOa}OapBOeETqAT\)>L:5>;8E9>M2;P8‹`?t‹?`“fRc]VbHi\9uh0|}DsKksPljChqCXsB]a:g[:lk@^nE]hF[d?S_5`a6\a1Ra=Q_:b\4cp=feFtg<\r>`jMdrCWtI[gAab8he?_8|{BfqIYlK_b4[a;oe@pw=`„DhqUXwK_iH\v>_sFPqG]bFXr=]q>hp@f|CdyPj‚Nm}HZ|M\kFhi8jp5e{EfuAYyFDsAP^;Ve,as:huCctSrmFrŠ@b…U^yN^€?ZnApx;[‡IivKOwCOnDLl8[`/_k-]{;bxIeq?h‰MYAbzd]~@_}OVrOSu@PpHqeCp‡IfzJmu:u‡h¦K›R{®^n[g„Ob„?oˆM{“>z”`c•X“†OnIƒ€C® {´dy´~„‚‚‚ŠJ“X…`j‘]~£bmžc¿‹k̳K†´VžžR°Èl‘È{·sZŒQQrLHn8eyFY€Z{m?n©b_vQaoR”‚\‘¹or®up¢Q…žW§šR•Zi‘[˜heŽZw~K§Id’[«†V†±T‹±GjµK^˜So…NnUu•ez—c‚´W¬…jk´[¤ˆJ†Ôl›HmPn|cš“<©ý“¢Á‹‹Ñ}~¡S~žb}®|Ьvw“\f„\…nÔ¥W¶ÏMÁAo§L€ŽD[¢\–ˆH½`}ÄVi™L”O†ÎkŸ¹i‘»b‹¥Ll Vtˆap˜e•I„¡R‚?n”J_‹Em‰?pak¬L‹œO“´mv¦fŸ`s¢Qx£Yw§e¨’Mžµ<­`±Ögƒ¼E¯°]êW}·U~™T¤×Zf·X‘™Rf’_qQ”–IyŒFx“@v‡Am¤HvˆIošRv˜He€Cr›TZƒNh†<|šRl°MjŠCyœTs–MqS|…IÉÿ[h±WŽ’]s³Z‡¬Sm™]²¯>†©G‡¦IvƒFqž@{9jƒ3o«LŽN£ÅyÃßr¶ó¯–ÒO‡³It•P‚¥Bu›q…šK°¼C·Rg—HŠSu¨PtŸR|®Oš¥]Ž´Km›O|¼Y^„:rIv–=n“>]‹cFc…?i…B}˜QˆJqŸQg“>m˜Iq‹7s“8y¨?jB—Vv‘^t“Grˆ_Ž<`„?f‰DiCiAf‹Af‰Oh—GvœIx™@uŒDo‹@fƒ>cƒi‡@c‡?]ƒYlF`hI^d?\g>be=Ti8Ql;H]8[V0_f2kbDcc9YnBRiMQh;T]:Ne=ad;ng8gg<]xG[aMUlB\[:Un:vc=eˆA_†YqjR]ƒG[rK_qJRyHKfJY_;Xn:X|F^|A[{JavVp~MmwN\~K^rLmy8xz5tv=c„Kn~RusF„Ž5N¢Y„AhreoˆY‚•h…¬_o’…sˆJ˜œvhÍn{‡d¦M‹‰S‰ºy—£ƒ‡¼‹~’jŒ€>§Mo¡S_Kt†;ƒ¨@Œž]yŸV…›O™¯Zƒ§cjžLq“4m¦u\bmŠE{ˆBt›jv–E‹œX˜¢_–¿N‘©Nv¶Pl–Tk„Uz”Gu¢Hn…Cq—Ch‘IsŒSp”Y›ª]h¬apŽHs²PsZŒ®_¦Ms³m~›X†­Ws¢s’bŒºŒwœZu LpÔ…{ˆHƒµM¹·F²XޏL~¨Oo›Hs‚8{W€Ž=}¡KgŠ@g>i‘Ig:o„9sŠUk“d`ƒ8gFqŒ@|’=…¥L¹Å â{k‹?dH€‰@~¢_|ªKxŽQˆŸV~[uš@~”=•­<„¯g„ž?ŒšcŒÀ‰‚ÀYkšRq’\ƒ¤A_ˆQc†Sl†Ut’ƒ~¯‡yN{Àgi‡Ur†DiVq–S‘¬i~¦Fš¯YqŒF~ƒMu“Qw–N€¬@|„@hŠOmPs‘Bp‡NV{2]}Bl‰?f‰@eEp•BjŒLx•Yf›JoG…²NrŸGz¹Gq‡:j;fPgŠAt‘IbAj”@]ŽEo”Vq–Td™CiŠC…§J^”^ŠAgFr¡pèÿŠéôRs—Mr•?lŽM|Dk“EsHuŽOxYZJk^AgqDeiIdnFowFi€ThpRcpDdpAouJdqJnhFfz„Qa•Jz€J:pŽgh…cdzJwMt”IbŽ\UŠT^rAZ|HeyEdr=s?b„D[‰Nd~Fb€HW}QurDe•__‡PTO[i7H6Oh6Uk4yx0|œCpUw‰Dr:q—Op¤N[“Td„Q€‹Cn¢[gŽPgBkZ\‡LYzIp‰D…”OqŸR”tx´PqScŒSg|Sp‚EtŒ@b•]Z€RM|KupBm“CqŠAq“D¢ŽD›Âi~¾s››eƼ”§ó™®Û“˜¶‹•^¦¢T‹²Vv°dÑ‹]™Àˆg˜_wG®UqšNµœc”»r˜Ÿ|¸m½®j†Ú–œ lÁSžŸMu›`­’HvÑq”e{Ts°‡}uW¡¡dxœot‰ft‰[t¡@wpXŸ­[nÂiŠxWµn}¨myhŠJmvE³€@šÀJ…¬rš—a{§Yš^ÍËNrÀ_Xi_Iyšk«Ÿs†›lg…LzQnfl™T˜œTm¬xm¨Zs‘e^ŒF|‹_Š¡\†ºKlšOt†Cp•G‡–@{›9Œ§GŒ£Kް`¨§b“ÍjŠ«O…³Tg˜Sm‹Mr“Pƒ \‚žJ~ªNm›B|œAm“IhzEk>pŽ@w˜Sh©Sg„DYŽLjMg’R€ŠVm£[”§]‰Åku Xu§GhMy•=všG‰ ~z©s{Ÿ[ˆ¦S{©^k;g„H†‰F‚¤yŽ®LŠ«Zf“E_†;u‰yŸB^†F]†7g‡DW|Eb…CdE_‡Be‰UgEl^/tq7eŒNbl^`iLgp>bj:Ro<[e:Tr5QoE_l8‚l5TJdp]_„Jv|[zŒGwˆSaW`}XUsH\kA\t>]{Ghx9vŠ:pJj„T—W¢Rn¢ba„^]rQso@j“Oy„LV‘O`z]pKTž[•{^d¯k`‹|`‚Ggp@^=dzSazGyt=^”S^vddwJd†Kc‰U|}Di—Lj„X_ˆQs‚8mX§\~¬MmŽe]ŒRw‰^_•Mo}Ku‹Bm’Jh”U{‘M|œNxžXX—Q`wG‡Kj¥b–PoˆFdO_8mˆEc’9bCn˜[oŠ9l‰>k“Ce–QjS{–HqšC^‰A[‘Fiƒ=eFuŠEt crœPašdsOtšR¾c_Fr‘RcLw Sq™MdŽLi‡I}«]ŸMl•A\MW…3WyC`ƒ:Y‚,Yƒ@d9h•InŽBiH‡P´Vb†4g†jv¨Hi‰;h7ušXršE|¢Gx¨W~ŸN‘º]‹¹Z€­dƒ´zt¦VhZ_‡A{šV|Ÿ`œ±tn§_v¡`«Â_q®[i“Rl—Mu¢d„«[g’=nMv¤T€¯ey£q{­Za…>^sBY‡[Tuc†d®Ö`p]¨‘¸rƒ¬SŒ¸o¿è®äÿ§¿íz™ÃRŒ˜|³Èe…¦]‚±_‹²Ol”D\€EY€A]‡EkŠAiŽHd€Gf‹Gj”PvŸZpšTl†Zv‘bœ¢l£­g™¥k m•¥h’£n¤w©`ƒ–R“”^‹“Ps‘Mo—Pr‹On€Lv‡VsŠQy‘T~•Us—Qp–J}šd¼Ç ¡ÁTr‰Bl’X£S~¦n“¼p…¤b‡¬Ry™S¢¹UšŸZ ©iœ¡Z§¤QŽ W ±e°¯n¯¯n|—pœª[«£l³Ãr¥¼‰óÿ‚ÌÙk£Œe‹”|´Â²âæ³Øì®ÈÌh›V¥i„–CYk=VoMsB›D~–7Mb'AQ0=T71D3'?@7OVAYE:ZAIeOg{Lm†N_uQh€Aq…?j’Z~¤`j{J`jITf9CV5C_@[pLb{?Yl6OhGLpMd€?f{AYk<

d(5P7JT#YgEn‹Cÿ£UYÞº‚pIlghƒgYiOY]>yS1zo7ƒkF6E?wP&ÿ±j\_‰‘M3b|\p3) lFkÁ^lM6Šd1§ƒQŽØ˜˜qN’sMŽ›dg˜RPxLNk6H]3Zk*yfEN[9\l5Pv3mq9^}RX“@sj=a|QSh?ƒvC‘Â|„WG>ŒKc\!cX1^R,Ž…Hs•[nvF„ÇwŠÉx{h~h;l¹msoPÒ~SÅîák™sœœVyÁs‹uP…|`®eMzzG–nk£m‚AžuX‡e¼¦Êw_‚dUŒbK]hCk†X{„Ik}S†G]rRKY' ˆcz†bv„TÄœÂÅ„§Ìjšcd¬h[wQ[b@n˜Vui@SO/ŒqFSI3JD/aB1ö¨ÍÀž­ˆ_ˆ_l¢\€nD‘_¦vN²…\ÿsa–¡rVb?z`†L5”kP¥rˆ—Ry‘YrR4O\(¦L½Ñy^vB[Y5`a6YQ5cEk„K|’WŒ…M_n<_j@kHU;[pHbJdwBWuD[…Rg’FQq4FX:3\94J7@?.BC*8G#J>*WM%nf2l}6JwRPIFab9=y;=HAeC*¡`/p RV™—RglRUBL_9d_4eu.`qF\g@ZcD`T8¢b9‚?rŸm\rgSWO7T:%?.& 5%Q8cc$I†=ZgIRY9~_:Š…E^pTQ^BXd7mZ,ob/tŒF}“Vq¬]t©e†Te§[ebYyoB†šTŒŸf”§hª¹†È‚Z´Ž:„o;C/"VB:W5`N0Qx.Yi@S?k?„h@He]JVGB`8;E.AC$J\1\R0ReM1[H*oh.m“N`’WGvOEZ>Oa4JX0QK8R\2BA*K3+G>-_S+f}>D€`ƒO4bI\jVWiGihFLoELI0K]$DU'evD”Ozše=}cL?#’w9_ŽnPlCQU9Cn=UF2n{8emPcnWhu@ƒw@R´j*ZIAC JY*b{.FgFZl'e‡<2U<"2"DHK"@@%Lc$g]8KoCc?1`Y3fk?O’M\cNJu@Ea'9\"BJ?T,OU)rt1ÃŒI¶\„d—[V‘\AaJ<–V;]rO•‚IQeO99$©E+~l\LBª]c·kffCoM9’Ni­]^pK žX^¼ˆÅ|I•abJhp;ÄcB„[R`U.QJ1IK'Ym.€ŸJ“­]¤¾h|·w’¥]­î”—ÿµƒà‰™´twg¥~YHŸfGr9Ot5Q‚FbzFh”Mll;cˆ›wjm=yƒCM¨fiK3 fÙšl»ï®è׎˜’y“±uww\‰Bµzdž}oxC±·tͰµ¨}¡¸~{æ“u»o‚–ls€X¥†jzx\ŒƒZ—ŠdNW,Rd?—‚Nh]}tQoWÃ{ZÌyjˆlTÕ‰z{ŒhWp?loB_O5HR/˜P.ezQw{fk”odžg‰ò¯ wQS_LqF‰mC„ˆ9Ÿ”Wê–`ö~|¢hb`Ea`2q•A¯\ª¤uv‡UTl:~G±¬Y‚ƒERh8dh8fe<§oPÌ©ˆ™Ð™›ÖsžRPj9’a9tmKx}HxŒD§ƒaŽ”T™Ìlc«ÿÀYuO†¦VSœB@G.„rPÿÿ‰Ö«ZPJ.`]9_€Ki~C‰bMOx8y\F«¾°­Ô€½µ¾æ—Ûºƒæž†â­ƒ¬®†ÿøÎoU¤Ž\Ÿƒ]õĪÁÿ§Äÿ }¨a…ž^x–T¤Ÿ]ÉÀi‹¨Y¼¼oÒÆ²éŒ†”O—›[¾ä­¶Ô…š¤h®µf‡ŸR„I‡‡WxO†žK‡gI“vJn…1Rl,_g4Ux9Yp6AN*R5-`P?wD4{dÁã´ºÿ´Ïù¢Ðpf’Usx9ZdM|xRm’;t§RÍl†£Y£…R¡”k®«­‹p¾ze‹…aÌš‡´‘d•t]ƒNz˜q¿j¢[sF[‚?QoFršºõ ˜¸^g„Or‚c’Vk|FVtD…‡dª¹†¸Îy®Ì~›½fˆ®w»¶Š ³w¡¾‡¿Ô®ØÕŒ¡›_o’Xe—dw»u…Ο²øÄÌÿÏÐü½¾Ê¢¶is’ap›kz¡pНk¡XaS„…\Œ}hœ¢ž×ùÎÐï«©Çv¨it“h†z–«„¥Õ«Äþ–˜Ðg™]¤œd£®c“¦Z…aŠž‡ªÑ ´Õ€”º—®Õ•žÕ¥¢ë²¬ò¦œÇdQy:Ja.\n'K> `X)uw4LO*_M+†P%€5u°c~£b€¡Tk³dO—gbbPxt=t˜Nœ[«UŸÑ‹šÀu»’PœwJoSRU/Za4]q2_„LI€Z=dO8T0=Q.?R/9R06B+8C(YB#Ur"`rBa|9[]@\J0\I6Fe<AI)DQ-AE1FO(Ia-Qn1Yl-dw>jr=Z†Nk|PRMXPDƒ}=c†S[L>Mm6AS7>>%8@%TG(SV)W\;DX:YG8fd8c‚Fe}Ab€BHrVJd=1V%VS!BY0GV8:G*ZL,Gc5HQ9BM/?X.RR5ZR/SP5HM7H^.T_2HX0[c3‰n@_±a¬Ps[o`=…M:W—aBM>JP*\<©˜AU_RaEC_52X"UO~B}NURrGh^9FYPbU0[„EEo@FUAN]0Mb=dS)<ƒERm;^‰Jlq:X‚=_Ž;(V1/7" 1!17DOBX$gO0}m?ltIolK]YIka:o›\eJ=nI?]);U dQrP9NN;Yh.cx9p‡>v}G]i^H=)pE,g^?h>¨¡XazdcQ6«½pY6;áT6•‚huWŠpI›iOžz`µq¯¼tÙŽditP‘lGc™POI,>H(D<SI$OI+n†ÝÁkÿŒgÿÿÿ•ÿÿ”ŸkŽC]b?¤b2qc@zwLak8S‘T›p8DtWm:=_2po2žžXg²p‡‘X©Šuðç•ÿÿÛ²¬zŒ p™¦_¥„h˜xj‹•j­¯]¡œf…XF|hJ‡aI«|a¶¸ÉÉ©‡Ðš–±{ ×™˜Å–KeD^YBƒUEŒeQo{B_gG–e<`yI¥I4heFrK7l4,^hNQj;[J0Vs@SgC‹pG„ƒh…b£‹hΪ¡TLr„KUyLrv>xkAak=­[›i´Ÿb¤×™‚„I}¨Nx²>«¾qšÍ—lŠSl€S®¬o~´W’ˆ:vEg²Qm}=ª¿sÝшðČƠrvžWNy7:>'fF3¸’Y{h¬kJi~PflLX_CEQ1fdUŸºrê壩ڛۥ”¼s\f7ŠZH‰H„”h’[—|P~Ÿc€›f®žoæ”pËo¥Ži£”[œƒi¾žq¹¥pŸ‰Vp~P†¢^xŸK[z<^€HniœÈ•ɲƒª¸jilFŒf–Œ[’]ƒœn{›o¥ÅŠ®ÙuËi´\s‹]{Œq•dŒ»ˆ§Ï²ÖŠÆŒŽ»u…V†}Z’“¿Ò³ËþÅÂëct–Xc‚OpŽ]sžy…¬q|X_‰IkzElpY Ž‚·²Œ´È‘µbx£cy˜^m›duŸw‹­Š®Èi€ªQt™^³pަ^‚¦^‰[•Ždƒ¥q‰ av™u„ŸŽ¤Í§«â±²æ°§ß‰œÃf]’3Bb2S}Wx§\f‘Jj^}®jv|7LsEaNl‰_|™p}¯›¢Ò¦£Ó|y‘u’¢r—£hxkƒ”U\|MZzLVvIQe=K\.Cn>\„@[tE_~Jo~HevF-M4F)1T-2S0DO0FR/CW5ac0_h-[s>Tn:Bd6CB3II)OV.¦R0h¨N:¡’GQ`PM*I_.Df9d\:Lt3RaDY[9v`6‰Y=w]=o^<^S?HN=[88hD([g4g^;cf9ut@L‹GPfT`G3ŠY1;­^?UlQM8FU69UB3BE$,P-0=*I>E`+NX*S]3Yh3j€:c…GVƒ_NsOƒ}Tž[`uT‘¯Gf“[5N9=*JZ!Bb37p2„R)AŽXx<.h\,KhHct?]s?R{I_`6`9`ju+1Z2/I$MV"Ab,?Q1gB/SL6[q7ubKƒYA…`Bw}i[™_R|=Ad3aR$IS985(S0"SBp€A~ãrf´xQA?Uc>K?0sI.oUDî´Ogͨÿ‡Y;•XgDo^>~sG›vY²šh‰á· †]»¿ƒ´â|[rri5`oD¾M3ˆ®nP¼PT^-LE'`N3P[7EB%`H*CY:SN5nxFOgG{†G°[mVBÇ„Nøf•ÿÀn“_:p>3/Cb2XK*Be9Y`+Uk:Zz7]ˆRLp;Žk8…°grlz{@“rUñ׋¼×‘†¹rŠV¢‹^Ÿˆf¤—pmªX’€R[p\uo[XMAχjÿİ풊»ì¥ˆrFÆ¿‘Ý›m‰fKf8XK6f8&y^C\ˆA„h¶Š]œÇ“_Zyb™¯{™Ôf|Cƒh?x–G…GŽ®qiˆqpGˆ’XÌŽR}ŒYN}@th=¥¬‚z«qxšSbˆGvsG€aÃ䛼áu‹½V‡¹j{†^öÉ™ÏuHS9HG6EO1LQ+–xkÃýϼí˜}ã„°ì—\²NŒTÜôŽìÖ˜ÿÛÁÿÿëФ~‰‹[º»›èãënܳ‰‡·a•¯i˜[¥Ÿc§«R_=dz?•†R}‡J•Y³·sœ˜Ow€;pBwItfGn{9qC]{6u`Eh‰=~‡Hdw2d|9yŒDRy>[yCbD˜”s’“]†_QpfEƒ|^ޤa·nªá¢·è¨ƒ…TgQ7ed7lxM–ƒ^¡vLnnO¾‚hŠtË™€³—f |[¯yZˆZƒ‰QumW¯‰_…zMlwDs¥gmžWc‘Cqžn‹À|™£cjZ±¯yp–N‹|TqmL€un¤“`c„‚Jy‡\šÂhƒ§Xxy]¬œy°–½þÄÑÿ¤ —Xƒn`“jiEPf2CY;kuv´º•ª¨q—_b…G`€]yž‚§³†••eonIil?spDfxQ”ŒZ¡Ry–Xv›XsŸ[i`r¤ruªgx—Yw›Ra“Du™Rt›Xe|Gr‚QvPopAgpC_oEcrOi‰jz—†°—£Ò¢›ÊwuœUm=Ee.AXGgwRlpA\g޶\g„F]ˆRfšTd¤|×”‚Ç”–Òª«Þ“¡µ~˜™`mm[yŒŠ¶¡]k{I\nOeaI~g:Wi8Uw%BF SR+­o>x·MB©˜EUdRC1cS(Fx4OiEVk=FM_QDwP/RqA_\O\S/ZO0QF5IJ7fB8^V0YeB\[=jq>;‚NLMH\W3•]=eŸNa’†S†WBsPL_LQk;em;{8‘£P·´TƒØvu›”\`7y[<@6r<sp/loUKZCE*FE)KV,|d<Ž>ˆ oršyn™gy–`cv][cO[`?>lL6L@MM*T^-Nl8Ai9:F0DG$>H&/E+1C./: 56;U(:N$>L-Fh-8e7WV0b+h…KYŽO{zU~šUf~eDTAGM?O](BY.PK)pJ)ni4g{LlSd†TliNBoN7Q?ED Qh/Wg7?ƒE8e=7S&_\,kyHPoWEf:LX=RZ1WI4SL4YS6m[9lY;mR@KS:NA-Wb0Fa9003YAiz8t‚U|~glcL˜k?˜”T’ÍxD}V<3OV#4\,SIU[(˜xWDÌu`u=Xo5Bn4Mm?Ez4CP*Hb&a]%MH6BI.5I2B?(jA)t}DFJH_S6nI?\D3J’ELK)e.cuXXTAZN:‚t9ÒÆuÕЃN×´H=/z='PnW‚Y1|OBÆ«ZÝÁv˜Ó‘kx_ˆš]Ž›thaJ®„Kÿ‰_óq^Æ¢‹ÿꬥ·Œn·osqO^~Mh5ÿù|xð»JŒ2W<%RjBFY5KM9IF9@Z3O*Y-Rf2°DtsFelC6O/cF¬](p»q_rIExF@];?)ˆd>P\c…Lq˜VU¨azž`w‹SiŠQƒd8ŒŒf˜Êoeˆ6pj:ŠS—xTw`Œ‘T…¤_§¬ƒÐ”‡½|y¿šètÙ„dÙ¹€t˜ocxGs„KÁ®†xçœmeEEH9_O?uSDvvAQ^?s\9WgKeI.žf7ŒiPY=3o•cW`AU]=K?,S`gS4QU9toA¥hL_hL‰kH^Y:•}__iLP\7RE*YE%g\1je9‘?pŸFY–[„zB¥¸ežh¨´Œ½Œ¼¸ŒbšW]d6Uw1qrI«ºŽÎÙ²Çå·›·|m›YjƒRiZ;gj@‚’Q†œh‚±dY™Doy7“oVÃÊŽªÂg“º\œ´k­eººu×Çš“Ò„^{J[a?=e:baCãÉ£ªÓŸ käê—·çu„°S•LÍÑ‹èÝÿÿ·ãÔ€·‘l†a„jIq[9fj@j˜N~’XxU}ŸaŸQ€¬X†®dx­[ˆ¦YžŒb­¿œüØÂª¸†‰­_js@^U:fi@]`4jwDaƒ@Œ~FzˆDw—Ph˜DUv5il._|=Gg3^a;q‡Q–›eƒnMwgAteJ…¤kφÍúÂ´ÛƒŠ…Thr3[j/OI?yO:`L;lTH–qPˆ~c€ˆb‘vW»†hÏΕ¦Ð|£¥g¢¼o¦¯lˆŒCVoDˆhƒ”Ldƒ?n‚X’š_iiAk[H§¢€£TujVe}QnnOumO„u[…Ju«[‰ŽdœŒ\h™zœÔ¥åКͦ}­™be`6U]GmsGVW/?K,;I->M3RO4QeJ|]aLm~qš¤NgY6a[*hi*QqGh¥cg™Kl…IqŠIi‘Pj“Tpœk¥lŠžau\u•C`?e†Lƒ•`‡ƒFZf6Vi7U[.If7Jd-?N4SO<`kLbzgˆw‘°ox”DIc1Ic5Ie7GW/F]5TƒU‚¡U^–T]Od™fkº¶Âý®´Ö˜šÈ¨¯Ý£ºÓŠÍœX‰{p°Ž®œJ]iFX^FN_BXj4Ql5FW8BV;U{Fb…H`}Mm~NWV-Mb)E_,@U/OP'jd$rˆ;š“Vp \9ŸŒ8Ww=D,OC"^X(kx3qLV’S^qR¨R6jr7HtcCMIS:)eG&\F.\L9V[8KV?\U<}w6[¦_c–}qŽZ‚†[{‘]lƒoru\xŸUzžcl¦W[’Xi‚F‡k3•‡:i„Vjyk[ŽT>nUCA2†=Rd,:Y[?].C\-JS'_R.hX3ehQ~jKjMu|UŒ…Ma”W^bcPG9MU63iA>P=LS+Eb3UV1F[,0I45;#?C?X+/S-/;(A0BJ /S+PD,Ek-KO8MK&]k/[wHrb0›¤QxgQ`XcZ8KU5VO1FP*HA0O: _Q(W\3„e7tyDltUQuQH[I[`*Et9QV7eU-D‘LMb;ej8\uEQcGPY7x]4ru0RjHQU2WF6Sd.M_MIn7@d@EKBrW15xG?I6Ma+lm4„…J‹™ct‡p€™\fMºeQWCLf<8eA*J*c@!V˜<@hNDQ)Z`.lm=C{A”C+Ž„Em¡o8…e1J/FL ab);tPj:!£‡@k¯uNzCU|:aF]‚N=PFG%Q_)Nˆ28N1HJ0_L<'-+x)[˜Q>ZC?A2VQ1T=>XO1M~7`)zbFgbRR_U\7ši3¹¯mPɨD<+hL(YJ1Šk;€bR¬ªYÍñˆw—f–¦C¸ªl¢¢k¨ˆVÖ`v¨m`°jõrQ³ml¹Ä„‹¸…u”cY­j–˜WÿÿÖ۷h‘Z{~6ož`y‘]bUI}ESv=2iZ:1n@,acExgHÔP1OƒSŒ‘nwq[]nMveJgfJ„a=qL-XF-o[7^^=ah;f}V_qG†]AˆtXf¢oTS7FE,kS5n]/Og0^b2±jI{E•R<¨{¥Í‘€¡qµ¦}^¥gizF9u4kjMªÑ¯°Ò®£Ó ‹{_\pOW˜[S‰OWe8•™fe’A|•Ne—KOx<…>‰Q‰¡N‚µb€›VžZ Ç²Å{ªØƒ­â–†Îk†ƒPhŸT‹‘g¿s\„•]Ú‚£ÓxM€uDÑ«ƒt‘T”VJª`Wì­•·É„½ï„¨i†X{ŸL‰‡MŸƒU‘”e”¥V†£[²§rɵqäªzÿ»«ÿ¹¹ôÿ©¿Ž^މR“ŠLrqC{pQvn@‡ŠGw‘I{FŸŠFŠˆGˆ‹Ifw+Nj,Ul/O`0Ej.vxH†^¨£a|†At]©Ä‹´è¢Áﮚ±W·|Cag0SH5kG9WI0rBF€fI˜kJ~jY½ˆv”p‚pï¾”Ò»v•©i¯¥~ĸg|t>Ys5c~BppI`„8aˆEg‚H]|Ffo@ob¦ª]qs`…`tmKbWMœŽUv¤Z¼cmiPq—Š»ä°ÏÄbreI‚h[xf>IU:PUBcmAEV,:F 1124&86kUUƒdl¢z…žjpŽJGm);Q*BW/HW.Qk9\„[o§z–؃—Åc±|ѦÅð“Á—›Å £É”š®aq‚K`Œ~ãÁ†µ@\jY~…Y‹J[v>UcBOdRbš\h¤TmD`cDStRSL#s`,]Œ:B…WB]RRK8F\<>`?AR1>L+X\&Yq:Xh=]l?oi=om>NpO7}[9O@HJ1RF-VL5_X9W`:nmFš„HŽÈjɰ‚Ÿ‡€°pryeg‡tN‚ Qr§mkœh`–YIwIBW9WX8vl/wOV‰b/ZK&7/E5?]DS.Tc)Ot4Ne;ch9mzDMcRFXNCF1F>)FG(-O1192=C MJ$Nj4JlNN(@C-:G&+:(5+?9;N"^U(B?:O;MD)^a-N€Kˆt5i’HXeNB`=HP-7R)FH!;Y+0I.@><@'QR,_v8W}EaqMVqMQTXm7Io59o4UR=fx7ZdSaDC€RN[;HU.YK/w[,IdH;R1NT,xj/i¥[o’^h•VK|XWYcP>CŽ;XB,Q1$+>:k(`G=XBO<1`E3@`GQC'Uy.Pi;^e0jQS`ML^2Wn7ÊŠE˜…Qѵb|UXa:šf5‹›bÁÇa—ŸTq¹U§­X³à~f‘yus:šŸX©‚Lž½ƒ”º~ª±«£|ȼƒØÕ›ŸÁžÓ¢u×ÿÁÂÇ’Otoc/uR=mS?_A.YU3mJ6nNAnwKiŽONl7NW3:a0BR4CE.j@)aM=—K4lª[W’PWt>Z{Q‡›XI{Pab6Tg2Št6\„[v‘N}ŒFgŠE•ŒI^|5¿d>sT‚kWl¨m‰€[ˆ™_fF4UH9OE7XC6vN;¢RFÑ­xnÍQe8VR'@U(2F*Wo;VrjBt€ZnUZy8HG)M1%GjMb†[ntIboHjnIºVMl¥myˆjY^=Z]4byY>d5[S0n^6ekF—†_j~XI].}gDo‰[€tMsoJFj6dY8owG}‰JRu=ƒdIek9\a5e;“shng=¤{^jÊ…œáˆMe:…uZ²Á›ÍÀ¡“Ü¡cVuyJ³¬……®ur€P”ƒIm‡Pž®fn–IUu5heBž‰^¦VqŽ>YN-zJÛÔª”Շ߼Ôð¢ºõ“±šf¹­{¶–du„Vªœy§¸g›Îzkµfx’V¬že†|I˜gNŸX¨{Q¦›iíÓºÿÿÿÈÎz’³^xZ€xLk…DrEˆ•a‘˜yЍ„ç¶Ê‚j†ˆ`À–u×ߥŸ¼‚ÃÅ‘]ˆMsƒHn‰IŠ„_¶Ï„±fcz4}x=‹wCi‘BIz38P%Di+<@&:A/Lk@`†Vqœvºs—¶dv°rˆÁ˜¼”‘ÕŠÁ~‘¯z”©fz›Xe…d¤Ÿ`”˜Hh}Sr™Vr‡HV];UF9fra—ÊtºS_w=IYHWsGNL1‡X,~Š:Y™WnzZUsN?oL;^?9M(3H(E=">H#XF(}V*F‰FuYVut:H”g9Uo,;=*3(56 9;"=A&HJ-Ld,m`7n7ŸpK\¡TJ…o^\PaiAWlE_cJp{Jnœ[§Œ^™Éwnɶu”zšin”n„z[•›Ju¡st‹rjœUa—^rpKaYAerRmwAP…P:aM(G1&=%G>!Ek#Cc?T_4Iu5Yj4r4q¸PJ·Œ/rw(B=+-G2Hb"=zEDU=YQ*Wg5@iD7?8=?#JT,IX/7Q2;=(6D);?%;0(4#$ 5*HIV_2NvIHY7Wb6bs5^ŽQGwF5SLA6#8Q&4E*:E#BN%U,CK+FU-`e9S~ARzMZtWZwKM}MHrDYd,hn+V}H~mIb›RzXyše[‹`YwEhzLek@DcCIS9S`7gv>^‡M`ˆZ`ŒP]…Zu’ZtŒRa‘M€yIY[{…RŒ‰KYu_zV»cPŽagKnŽLU“gdŠMFŽ]4T7=L^R LW4OY3Ec7mb* ¥Mn±pLSUqC@j>4T/;KeL!d7\lBSH5__/€{9J~GTcNSz==a2HJ3eD0*a1`.9?0R/#Ol;T]JP)7E*D7mY?o[0X†MQmB?Y6N;&8>$ '=&GD#r:$fBE†³p{EDq@ p5a‹\n~Hh‚Df~Ddq;Mx8Qw5\j1pn5~a8‹Z‘¯rewS‡wVf»}_œgf‡\š{b­„l‡dYßÅ€dšk]|OfˆNEg=n{I†mEfG/ÌcB¦µymLTTQp8|„]„¿“™Ä“k´…j©lf…O‹s@uß™~LG}€W[hItgDv‚UMK1ye?vkJš‚bbi?V_3alEkZmcJSqGF€EwzOˆµ~ËìµÊŒƒÒš[¼yTa>DX69T-\eChY0¼´Ž¬ÿ¨Zr5£”]½¨†›Ë‘ ±Œ‰œj}Š^…µy–Њpª]Ž£h‰¿v’šZ]‚:`‚AvyAyrK|Ubz<_~=›‡Y¬¡e£Å€¦˜Z¶ÑvÆÂrÉ–e¼µw—œc«ƒU›a}¬X»Ñ{U‰J”—[av:co?œ…bžŒRЀtß…jö‘b³™W—‘\Ó°xœg“‘V^sC’ˆ\ƪ~ÿ¤}Îe¬šl˜ˆ_“ƒZ…f[¬¿†Ù³†x|Gj`;RW3|cPÝ¡p»•Z³Rƒ‘Dv’X_”Oj†D4u*Jj/K}9iŽNz®my§P\t6lˆaœœ{¼Û–„Gih@_lCsjNnqCtLƒtQ”rK~WA–\Z–xNycC³{bÆ€oÍŒˆÊÀ¿²lpšNe•Sm–]m‘Uj‰C`Rƒ¥]yEkyD†oJlnYŸ‰i˜¨q—¯dÌœ}ÚŒý£¼§i –\Š^…‰KZL6W`?Z_M‰k¨µ}§¹p†“^pWdƒe„>:F-:@1CY3GZ;KVDO_QmqAXb.HZ1L[4Ic6Ja7FV1GQ<*0)$5 *3%::RMLj+PtBzY=—\/vwBŒZg‘_‰}e„fM{jSv”Uq®u Œa޽rh°–{•{r˜ba€dzYLŒvDb„`m`ZrŽ@r–Tgu[dbRZnUSsB;s=2P-1H7I"UU*Um.H‚AQa-l1I}5@[SOR6Ib0A];GO:F\6GoDBmOCY;Q"Z.RD"FX)6J3E8'SN.[g=YlDZpRXtQ\„V@‰GBX7QR+aY.rd?x‰L›sXsR`sYdc;Wc;VX4Hb=JU>NM7_jArŽGažbf–Z‡°ib¼qZ˜``„Mhz>^„JYsLos?ssQ¤‹Y_Ô…^mgvyAxŒ]m˜kmPJ“b:dH7K*K\"I_96`5:K+``'xo:jhJ]{>UŽSUw@@†V3{IFR+:m/2H&0:FBBU#ea,X€4QeGOp0im@Xn4Nr5EP%?<)LB4”v9tpRZL?>E1XB.SW:{`6i´i^xL|l;M~a\j7mœGN“XBk0X>$¸S2r°qgªnm–EEn5Q>SSO]B?W1i:ˆWUÀuid4LWTtA[W?]O:dj8[O[”Ij0fq<;d1lATŽT^Z+aNdl?|‚0†½dT”KNv7fj8hoAY>+–|WErZc4(ÓcGpÄ}SK6a:2IC2t4&­Í{~œjq®mž¡cdÔ‚o¢[ab6Q[-ÿ_Jœ§lû‹mkkP\t@—©‡¡Ã•ÁšŽ¬|®Ï“y§p\ŽaŠvLX`9]]IQ\8RoJXxF_[4yc4|lQucHBf9Qj=cqC_f@otNm]QtBtS¦­…ݘ¨€žµŒ¸xc|Sg¦yR _hN==Y,¤gTŠö—WMl‚E•¥h‡¦en“ZWo>‘º„®Þ¡kÇxxS¡Èo{¥Qk~@b„G‚N™¨ae™Z~¡[n—GrnH©i‘|G«nF…–Z…‡O¬¯t­½o½¤_È‹a§ˆP²—P}•JÞ’WŒ§VO¸·uŸ§`ÏňÂá{§¿lñ¨…¶±z‡¡`‘¨V˜ŒT’‰K—W}}T…|\–ĩa°Š[¡€\“}]˜mSwqQq`¬³|¸¥„sKtwDkk>‹WBW>|vS{°QiŒ@y£Yo–T`Œ;UP.R{1Ys>_~P‹S_X._a<›£~‡£ÀÜ…z…GerBa^B…\MˆxIxZœ`y‰Q†lP‚_Q¶xV‚kQ§sXªlRxxQ”b^±¨p–¸aqŠGnU}—\i‰Aex>vDsJnzDi‰KЇZß¸Ššâˆ¬Û‹ë¿s°¢s‘¶j£¬k•³k„’R^_A_kHl“uŽÐš½îŽž¯bzlPqk[zž‡±¥w”ZjlKgmLus\ˆrfŽˆq{€LMS,>Y0Hc:GuC\ŠO]‘BDf5G\FWp;WxK[ˆ[i˜ew˜PYJn@b}Hf”Tj˜`s _~£[ˆ‹n¥¡j–‡]†z]ŽzU‹ƒr¡ÍžÔ›«Ëž­ÔƒŒšHST6=b6Kt3FM'-+*BR*:M,5L(6E*M?%@J"BT2w>/Ÿs)@¶l;S5<7A6%,G&,A12C#SEh`!JŽA]jWcX4…^0³shI[s\ktC{›?˜L˜‘Xx~r\}_IuR9`@8P.DMFS FX*cR.M‡A:VH:<4G=#Ii-œR4Û‡@‘ä†7çß-bŒ-1'K'cPQ‹KV|ZL‚NRfChh@pwIsŽ]S’tEjabj=d{BQzQcŠLa|?…Œ?S¦U5T5d8@Y(@'C2#_],U‘U^}SmzQ{—T†²k¹nsŸsjšbU’aOnGKf,^P0w8dh–hX`¾gevgww9xŽ_YŠXpwLFtIB`9:W-_`)RY.iN:F#JS@M)5B-`I^r6c€Jvq:q£`b³vX¢f3y[1=2VL(Y‚BEpCD\,Zll,„”MBKPc1La)ngDX^yc@DŠSN4${U-ÃÀ„v±†{‚dIMeS4}ÇrgG<„‹d‡£mˆÁrƒš_fwL††Cë|M¹|LX3)hyXn›p­‚‹¨v¡Ã‡ˆ¬{×¾˜jšaXU@qqUdc9f}PW¡weoO]k@‚‚KVx=QqDYsCPa7jˆPZT[lF“wFoQ2{vW͸ŠÌ£‚ÛŸ‘e˜½‘†ÈŒ‚¦q¯¤‚À‡‡„OGo@•Œ\‚å”W€;e>{€Ra|S€`e~Pª¢v—£w‡£o¬aowJrtBTp7n…DcœJVe9io>]x9l|Mh|FvŠK®qyŒZyzJ<±•g¦Ä~¢ÁtЇYlŒCnžW®¨]¤§[œÈa—ÄkÚÔxÿ·sÿתîí}Ú¦eèÀ„ÿ¡Šñ´€Hq…F„…I‡zT…mH‡pM‘…PZt<^GŸ…d©`†Š[«Œ\œ‡j¥¥o—tfr{MoZ?{Z>^`7aaIº•†›É…w¼YYx6i{>fx@D\0Sl5_ŽY‹’Ypq@HS*HS-biF”¤{¯Ûnr‰MŒiFtYBqfBŽ{O„U“Ÿr˜¸pž­l²šn¶ƒn“‚b yd¶€`ª†Yhc;[_K±ŠXk>Md?etbq«`Tw;i€Hƒ›[q•Wy–RhŽX­›„ÿË ÿÿ¯âÇrÑ‘sº¡o¨Àp›¢To|IaaA]gP‡”’Îß›¼²i‰‰Rz‘p–«–Ʊ}¤™o•¢pÁ™_¡{R}nY…†f|’S^kCXwO_“Q_—Zk¢]u®kk¤SQvA[yI\rFb„eq˜h€™n…œ_zƒ?Se4_{CfKn˜Vq•Vj^‰vº³q¬k®Œ_€b—¥¯Ô¶ÁñŸŽÊ}˜¬ar†K[‰W[ŒHS_9;I%/;$3>-@I>aeKczGgŸ}•Ö¦·â²Àî½Ë÷¹Êü»¼âœ¶iy k{«kiSWuRk†SˆyEdp<]`9T`@_iGklEf[6`d;VsBUeF^dGl`A\bGRK-WY-^n=OqOMiPC[N=VE6P75J.9F*BG'_ˆ?;AL<$8H)/?21=(=O&hL [l(DNU_C]Z0‹]+up0cTq[NTS(e>tv5a•[JaQiK^\6tcBymKZ}_CqhLgHdwAp~Aq‡RtXkžeu u~i|£m‚¨nnÁsv¤}i®u^¤ydŠ\X†E@”MHh@Dp/:p88W1MoCRhFCv??[27V.:E(MH(bX4TKtv9CkDi3bW4n}R>ZAŽ\7^¾eVeW[i7[pBS|H[I@d?E\(2O,JA!>D0/Q69?!0[%5E$<<[:!gK$GZ8^f7~z5™ŸV“¶‹mÌž`µ•„ nN„]?S-o]=hy:OpKSZ9h„:j˜IdzB‘{3”gt x•šTš·{“Ÿtu›_|›Yÿ¦j£ÝË\¤vwn@QqFys8Œ§TnqJOpGQg-Y~9lw7_zCh^2Mf?NJ)=9/`J1enD:iHL@(Z2bE0nd2_ŠDYb=’lIlpZzdD†pSp{Tc†MwoI]‡Pnt=“dE˜d~o`gxCmQ3``B^~RQS6`\1gsSW6'cK1¥nEaµUSgsQ†œZ`V?gfC/zŸkvi\”U^i=sPÍ _ºá´œÌ«eµzžiE¶t+*$]7'T8Ž[³¨kŠQ®PlT‚]DzuSwnJs‰Wnh>–u[›‘ui¸y—~TVi^G5[P:PN3brFsyIkƒYtˆal•YR}CXsENg9mo:~Ž^drNœ¦cc‹WC_6VZ.‹~R¾¯‚‘Â…¢O¢·€Ÿe‰ƒ]‹Sœ¨eŧ[€S¨r€ÌvP4ri=Yk@WS0BS+VP:\pKYj:c…GRW.Ld/Kc,Jh/fj0_l;\vJG[,Mp.Ÿez¨mm—O¹k‹˜[w…Mœ‚\ÙÖŸ¿ÿ©ºÁwpŒFpv9ŒšM‰‡U’ž^ÇÕˆäÿ¬õÿ»½ÿ“Ú×|ª Q¤˜uÞÁ…Ýȇ߯ir‰E°s~‹RŸ£Q¹`ŒÀy´ºzœÂw¡Ã„È€mˆ|[ ‹\¨¡pÛʉ¦±Wb~0Yk*d{7„‰I†wM†”_žÉ›¼Ø’¡±qT¨LJm2cv:Qd?gy=|‘L[‰D]X3D>-hn9\uF–®t¦ÐprmGtuZ†Š]‰|I†j]¥šp¶´†ÜԻݣÄç¤Çë¢ÚÈ…ƒk¡£o¡€KpfEsŽaw’Ff|H |UpY§jq”EjƒHrŠMˆ]šŽ[ž}S¡œ€¬ÑŠÿÕ©ò许xšÍ|‡·ei›Wzm¤py¤„´Â“¤ ekOsY²¶™ÇãžØÆ‚´¯y›œYwƒcz“`‰’h€ef‹]^…W`Y{™b‚ºu®¶u”µw‘²ef‘Rg‘ce d\•p„ªr•Zx„Pwp3Ni7MqDhKrœLf”Yz¨}£Õ•»Ê„ÊšY’~PŠ‚j¨³œ±ÞªÄ܇›¬bn˜UjŒSu|XyjObsJ`tZ?JC3>M.5Q?657?5(GP,VB/;_15>8n0/”]+B¥c7gŠ9"=N-AX*]S$=t.>`G?P/KG&[N%b[*^W9OU:NK:\>6U1;P'@W0CV,EV(>V/M[-Gua)Gd+[M:dW9l]@d™cDZ<_<+so?†‹Nƒ[K†E1tB-eb?†hGneRl~OO‚NM_>\f5XA.‡O4d¤mO‘Wk`5Œw>f}RMe6pB(O s@G)\C(~yA‚ăÍè~—ʇ[iDjlbiA]ŒGIB,[4~H-~oA–hHW£hdv9–b>vš_oŠ]…RlŸc–uF¦³ƒ­Ð”“ܰ™¹’aÈw9b<|=1ajF¨U4Ƽ…Ñ£e¾¦iƒÓ~àž…Î„i…LZt1bQ2N/!‚iLCE/…Q1[kK\‡Pfb9{c1}xCk¤Fm…MQ~@or;do;kzIKe8¢hcžcbŒQorHn{Fbs>\xI`…LOk1ZC#Zl2wrLq{IWh7E_:j^5^`5zzNž¢woÄgFa)Uf0R{CEZ0KpMMnAn‚Uo˜cM€BMf6Kx!9M)KY(F[$>a49O29F.;L)QH%VQ'bV:I[;R^7]Z8Žu9~­Uh{r•_qšW`ˆ_crOh‡GkyCn‡P\ŠV^‡[Xr_CfLjO::_1.DK.>#?2!IM V_)Ph.0gC99.D8ODUT&J]8EY:YjAazD^RaŠWkŽRc`c]U[JvUOg=YkˆICM8FR.AQ2?a3>S/5E(T?"Pq3TbQYt7V^GebBlzXqŒfc†bW€V[ˆXP‡VU‰`^tV[Q_bPwQ>mpQc‚ZE`HWP4QZ8eL:˜cF‰¦e9›—QB/Pe=@b6AC+Kd1”_1XšO:YHHB*Sf3GxE?Z7EZ.6F*$195*A 42#EFDl.<>\A&Vr=Z>7{K6¿‡?„rNLK<‚]=ð€ArÜ®lN|²xM‚RFZ4DU;^H3‰i@h°tbbNZ_3r:(MU;gh2a‰KZo>ÈnAn}oHoO~?+ŠRYuHSA(v\< kPkPw†[z­{µŽh¸£Šc†qKO8?^2pM0mHp„gx—\vºqU§gWe6ŽV3‚·~oUJDfU]Z9ÐŒ[šÿ´¢­`{–][ˆRzrV‹nWN[4Nm4i§US™]\iC]ŒE.M-lW.r<,¬‡ZŠ^‚¤s­…Pÿ–eÿœoíÖ¹ÒÃØÉ¶©¦ m¨Š[¡‰hš©t’•kewS¤‚El€7pƒ1ÝqAÞ³Zê¬dº¡c¤ƒbµŽg`vHYk78X3PQ:Zf=n{^TEp“A]”UUY5Lf8O…MP\1Fi3z…L¥Ÿs_£ZNj:LFt–^S—[e‚Rs—hr†XXyEHyDJc6Io8‚oSi4gxM`?Pi0Rr6QW6ƒƒXŠš`˜»y˜Â‚v¯g •a±W`}<•q”Ù¢‚Ҟǭ§]DYM'˜sR¶¿l³Îs‰¡[v—I‹€T£|[üæ²ìÿÃÚý‘¹Þs“Òc‰¸[~˜eŠzS”Q‹º^¬ŒÄU…sP­Ž€ªÿ·½ÿº‰é~Úev¢I{ŒAml];Wt@u”MPd0Fk)mzGÎÁux>jN8cZ?pW<ŽaH“vMaisCfˆQxt›¿´«o‰_ˆ‰k™™‰°Ëš®Älƒ StXƒ”Vƒ¦KužFv¤Tr‰FsmG‰gKzMopG`}R[†_t£y„º{”əťÁ’¿Ë’­µcktHTi:Pg8M_@_u>Wf=^p@LnKbtDYn6UlBftCnw6PkZh4Xa:NeNoyIHCGBMA9N0KM6j}O?JHX0Vb@;S?7D:7F.9I0CV/Jk(Ak2Jb8Aa:El=Vf9a[.OW7B[@LY6_e2Œy;pœOj¢muŽ\fŠWXgRS`APm9[eCUm@elEU‚HJy[B`=XS<:O(7B:1J),4(>2TH Vf,,zD,>:2< 5@9> DS,NX8[a8fiB\lG^nISn@PrFViCNpFLlA]sBt>_zHavI`|?e‹N^QPJ?qC5]97Q$N[+S†8ExKDQ->c/Ae8He0cf-?‹SN7¥@+K¤bBTIKG@5U,9C)EN!Db'I`+?Z,Ca(W\ Vm.cb/iq;›qG•¢y·—¾­’ãÏeÛÊH¥XV/TG.>a.3A0=:X8$lzA~rO‘cCNI9nL.€ƒ\˜yI–ia{{J“sHy§Qf[rS9GqS_i>¥¸lN€e[I-TQ(„B*pM4Nph>Ub3i}Ep‘AGj6Wp1t„MwˆK¥q•¤k³ÆˆˆÊsmgAlT2pSÀè¹ÅóȼôÈŸØ£’Éw|£YhvBnyL¶°v³“d©tW–œ\‡ÍsiOßÈìÿ°¬ê—²_”Ãc”Ág¾‚`Ȥ~£Ã…}¯H³¥fæà–uŠVã{´Ë çÿÔÖñ€¢Ìeœ·n}~Yu€`{sR||K_k;zIsg7zFZ“_zAYyRTnMS_DLP2`1DY4Td*y|:V”EArMQ^-er/G¢]F{eUg5Lq2VsX_L=MD?H:FD,LP)J]/iR,~eIrL®†Z˜–p°ž{¢»‹x·¬bŽiŸ{M›ƒBeOda8G?Ka9NW@]s6iwDH\6zj,n¦\NƒeBnLTf4Pf8Mƒ?ršYk?ndF`tCº’]x±mO†XJa.YL(cL,h^?lcIu^>b†P[‚B”u7”{LgxMbn8ug;gvNnOofGl`H\A4g3(d]AZ=3ˆŸ_|Âz\[^b7fwOfa=c“]d{QdŽVYl6q|I|€?ƒw\‰bU³œfÏâ‹|ךN}XTF1:E-Ka3OH-;I)RS'¢ÌigƒR\kO·—L¥°slJ„T:•sS•–_ƒV‘WCl•]ir7—\;`J;dl5Um>yb:wZ9RG9zŸa[D8lMB´|oS@0J2,vUDÒ¡yÿ˪{ˆO¹‹X¸½ƒ»ó­žá¦´ç¬Ïlj̳֕¤¸†°yƒc²cBމ\veC„sG|_?Gh.`C)™Qn°mkuJfc7OP6…hKƒ^Fm£cVuZBm}9Rj7XvByNŒ¨m­È|uvGßИ•Ò€cdCe„L~^RÌСÄð¾»à»±ß¶”ÖŸ±d‹h£’Ù¸‚®‰]†•_¨p ¡_dŽF¶¬‚¨Öx¹È‰³ÿ¶—ב Éxjy<€[Æ¥}“§bh£DŸ©X€¥U»”v®™…áÿ£—¿MŒvI”\K­}n½pŠ]Žƒ^ˆŠj—rI[`Dr„Z‡¼jh¢UoDo‰Gd{@™‘V€ƒPvA[{N£®Wk•3††RÄqYŒ‘h‚¶f|œe£Å‡”Å€Ëvc…Mks5hz]ŠÏ›¤ç‰’­`Žœd‡¥Qs„Hw˜Mj•KcTj•dz™YgLxbu‘GX^/`J-`KYtPY„Km™Mv”FvŒXŒ¤n…¶| Â{£¿Rv•BrsF†kK€{^Š—M_4Ij5Zl5^w3Ci@_iVŽ”fŠ¥Vl›d‘Ér“»j’«f‹CC^5SkPv‰Mco;Sh[oNv‡\TmwNp{Qiw=Ob@WtDPk=DiF[s@Vg4>U9BpSZƒLWdGFLEPG:Qc4ZY;CO3FS:CD4>>*P[1_`AplHA|^`G\uX:ZY=€P?‡Ft†ukgdXnNApF]cIm{@nˆRcWXXZsHLoALhJDe9UU2HT/ZU6aT.Gg2EU<^X,f^6`q@QqGPV>UA4TH-S_5=R1gU5“j/`’^KfYEjBDl=M]@9s11G29F(ElAVvG_bCXY=Rd>8jIC15B2#:F+@G.*Z,/G6ŒfkçoZ~Q{QBxZCpXCªdIµŸa…¼›z¹–]¶`yc…XX~R_|P^ƒGGX-Žr3o»Ve™p]y[XA™ŠD‹Áv:¡‹1YB870A$.2$G8 N[)cq:`hAhi:J`8>W/ZI'eZ1y|>S™N=B7u`6aR4og?~xSœ£ãÿÏËÿžev5m^]ÄÒ«¶Ò‚v²hh®Ws¨Pgªd{µ^”eˆšg…’i‡`|‡XytayšNVd5NR>fjT`zVe•gr±fO„CHS7hS;bqYƒ¡rƒ“Y‚œi]ŽDJy>WtT”¤q²v}ªov—eys§¼¨Ëé»ÇóºëñÃõëÕþþÍÔùÌéÿÞòÿ±ÎõŒ½âv¬°Y®˜c¤¬mƒ˜NZwDRsFh†Mv‰aœªz³¡yº•hŸ€W‹uImi7_cJuU|CfŒEW{5Mv]…¢‚˜Ï„§Ãc~‹E]rFYXD[L’sWŠY††M[u-@_)Go3Wp;\VFsm\{Ÿ]q¢[‰¤ZktAXM3Xi0A\:LeEq~>Uk2Qj:bq;MkHWƒ[l‡JdgC`UDogVpqLamOnwTX€XX]_YZ‹SIƒb]ŠflmEnHIMGYVD`xA\mCRd>?P8BQ5mU/{‰ClŒ\]yb:ibGFOXF2PH)r<)f>w|nUZOdNW_Mfg?i}Il†TV}OJuK]S4[Z4JbBQiAVl19b3IR8UH'EU(KW1fX,Oh=WcIMb3DW4F:,MH-:X5@D8jK)jt6GkJZSERb8IkHedDC@KhL~{J|§m;‡oRHHW@^X:5s>17H*0';3#RJ*Cf4:fJDR1;O)5H$FMOV'Ka/Ia]TFL+LL&;W7K[1?f*IV4EJ/:R8NR2ce,XGUvNhr>¢r9`Ãm:’šAV@F_/7o=AN4^L-~e-”›CeÃk6™‡BK=BQ&=M-8R*1A.9@$ZV+Uo>8[4A=(FY'K]@DVAcCd\>niE…d9ƒY‘’j‹ˆh€–pm–wd¡vLŒQaq<ƒ’MvŸKUŒ[[nFqt<’U1£uH}Ù›PÒ¥G’v7hDJK2?O1W`2ic4XŒPD‰SKiAIƒK_nHws6‡VFz];O(<> EQ]e2\u:cxJlr<]FIf;aH/Mx@jr4l–\v‚MxzTGyRLe:EP-W?!me2YV>Œ[2k‡jFI0‚Q1N¥qYc:|l9¶Q¨£l[z]€E8~»aâvRÄÿ¨H…wDA-a5*K3UN6Y=%`f+aeEewA­AsQž`R¢bPm}iocSbhMkmQg€Y‡b¢¢`±¹‰fä–TmDE`AšO6wŒlb…[zH]ŠOQ|=TQ*vGq|F”¶fì³i~ð¹reEcbInƒR_¥bVz?Po?PY(TiGœÜ™w‘U¾Tâ‚]°~e¤l™‘_z›dx’XyS]ŽV}|9ky?Š`_ŠT÷ˆQ‘ÿ»soO^„N…rOâÇ{^]9qfKžgTÿéµ|Ÿo°kM}©p—`{—ba‡YyH9†sP•¨z޳}—¢lv™`rvSŠŽga˜]ÁvK€€QyuJ‰…L®ds™_´‘YƒwUn}UzdAnƒ_GiFsb=d•W¯Á„¹|¥©x€XúlW\7gl:huxaX„—Zgn?\^G‹`£q¼‹Àws¡XZ†CHV4YK6f\Gq~KszK~Nj¢TN~K^pR’z…¡pfƒ¥|ްմ•Ĩ†¯¯ŽÉÙ»ÓñÆäÿÌáø“¯²b•…Nri3;?!2?7muEgv=ZvEh…PhE^~Ml‡QMj5;I4KL4^Q3MP1TY/Ye:Qe>f‡@[„3Ja=n[`Ÿ¡\x}AdfD„aY”pVi`G…nP…}\–‘g¥N^p2Tp4ZyC}jSw—k“¼]{F]`>oP0_R2Sf-HXl{KVwTMwP>aE0M9W6,pK&q[1vbDolQfnWe]W:HG110I5"¡Eu5<’wFg>;S.[8,uD#OQ5j\>Xi3BqI'NX-O`DPW>|nz>0QJ2G%I>MM"A]-CQ&F]-g`;t5M¦_@UW=J0C7%GP#Ol4>^@8O8JW-Rd2_{9hDlt>P‹LP_Jˆ]3‹;B­„JgpO]2Ci86`A4D,KK)n[/d=N£UQW3pc-r—Nm¥af^f•`~‰?f­oIh8n4BO+Pm7Y@g†Bi“KyˆTe©d~‹M˜³cpÂg‰vFŽ{?TXPOV4Qd5E])AT*K[-ˆ]/Le8—W,E^F@+ti5NuYlh5r|Iâ’Kz·†[VJgA4£l5ÿÃw’ †—Úx1…xC—‰fs¹q±}Cž|`®™t–˜x“Úm¹}U¡[n‹VG„aQe>un/b‰J[{38R'ka5Pj4UY6cpH^‘If=Rx=J^+HZ-ezMƒ¯h•Á‡¨°my—V®žy›ÎŒx·k›žg´kqWJ¡›€±ÐЍ¯u…WmeEO…Lq{H˜¸u±¶¢±lra9¯nY¿Á…®—v”݈’ÙzoÙfI?Xr8O]8’„_}žNbšF„›ek«Uro>^t7`^1|uIœšf±ž`{Cgz^p…j‡´’ÈØ¯ÏÞžœZ†lD‹xP¡‚K˜€O†ŠZrVt§VeˆCtuBnrN‰„Mrg9Zg6Zg8rŒH–£XogX§”…ǰzØ¡f¯Y…yHwjL†m]¦Œn­ Ñú«¸Ù–ªÛœº×Ž¢ÏŒ»Ï—¤Èƒ—Žeš‰hœgulHj[7zYP‰“Ux}F™S~³`pšZ~„fŠªhk›dgSm‘QTw>Eb[b‘gR‚An–Hv¬`|§\cŽay˜z®oz|YŽ|vÇ™y¨‹j‰tjŸ‰‹ÈÀ¡è⨿ÀuŽŽS|ƒDbd7BI/@J8StMZtFUyB_†LgJYv@ZkFjvOc…Ld^BdX6\U;oYBabCpuRnvD_†;^;DfA`}Omp8Yd7LM;VZRxgO`Lv^Bzl]¨Œl¦T{9Pn6SnQg€h¾n¡CYq9IUbl8Z^1N\5YiGmlM†lµ_•E_sCbnDef@Zi;UW0FL5KPBjcRiuWdxZm‡fp‘hfj8cyHTiQGdLHaC@];1E;9I22C-ME*hX<;nH6;M1/#!E&ºL„w0MrhBVNGQ4HM0FO1Ua9Nd81P88:)EBFY%EH3hU3R.hc;FrK?f>A].I\2EZ5:_FPS8?W-FN6RM-^^1Zj?{€Kh—MSz[@YE7C8]9&Jl&{lO£žd¯…K‰8\K2H17D-CA&UO+k])YLPih]CLP.4\3:C*DK ;d.cM8gn/I†d.c?*F))145[5MP'Ee:>h:CQ%@H RL/N]CJU?RZ7P{?eX?Xo6@fK^R8\l/XK.gQ0e€P]‰`_‰cc‹Zfˆ_fLcuOaMp‘Tl•TqiCN„ADoIHX'YK BkG@m5NJ'9O,g[Y~os¥|x˜ˆ‡~¶‰kŽ…eŽ€Zq‚O^|QcQQgER^Re‚RYwYjœ]už\x¡ew£V]ˆBXrFenA]Z4T\9\_?]_?h`?vpS}ƒBb?`}LhŽU{„@Q`2QF4XKN}‚u‰‰YkmKvdMnxYž‚[—wGhe4N\6_~b¦²p™Vjn;UkA^{Lk„Pa‹GOm2B[6GX>\pGlzC\wIktD]e:^ƒY„ªd”®dgžc\‹QQg:Zb=T\8FO5HN@biJgpIioRq€`†V]O*@m4>pGXR@kR:UX?8`@6Y'ZE8-<:3#,E*59*S>%VS%LP1FQ+FN)BI,UQ.Y`44V2.7387XH#Qk/Cc<9RCX0KN.OR*Wc=…~Ar‡QPnZBeF9K69@.X>uf+‘_c˜EhoEIF:W/&Ue.XaMU;OY/Ol.nuAaFYtRO`F…\7WŽNQpfbo0d9eM\ƒN;pSEB1:O) =CTTUY*<ˆCSP?nZ-g•LI”c;oB0Z658%IABc6UR9aY6H‡I?`M3e6MH@G'EK0LJ2^a6FsDFh9LR)PN7m\9a[g4>T0h^6SoO;]>]_2Šx>¤‹A~½ŠtS™}Q™‘eœÄ‹„ߢÊœo½€d–\`ŽXpm1fƒIJƒX+\C2E6=H,CO#^_(®j/±Y[{YGyN?Q86B#hOmI%TK:`Y8ŠkckB’ŒNyŒcp¤ahqHh“gZLFe,$FF1C2#N8 tM-‰l1 VC‚•jz©…–Vœkƒ‡aš]o˜Xj{Ac_:hd7wZ0È£LɽБš{\†cXrTU–Tq^5–Ìn¨Æ‰³¡`·¦SmgG“i@á­zœ½™n“albALP4tC&XV;ˆg%¹oKÿÄŒx̤è›]dw_PO=Íb[¼£swf}qL˜€Q„“J œgK¦mvj3…oy€d¸º’stS]z:WU1×q<½œa…U„yTq°tX}UOrG2K+34D<%SP:“hH£‡cÛÕÆù o‡On–Xx:ˆ„=†XngB\g1cD{P\U8ZT5xfC»™fšœk®‹\¨xYvnHˆ_|¦bƒtHybA}s;^l=t~Q–gfƒ[b„Yl†RU{QE`2@;#F>&jjD©ÚŠ@Z5;M(^€QZsB[L3|sDWy=‹xJŠjIca=[cn|Gqr>r{7i†6lx:_AEc.nmA`€7Kk/abG—¤ma‚wFsuAvo9HI/ªjQ†‰a¤º’¥½„›¬c‘œ_‘ˆ`”®kv›J}r2€w:um:sT0qcZa4QT4LICnqo·µ‡›«nuŒO^~BWuEUhM]nSs‡CCj8UuHƒ}S‚sD~<^t9anC`mKxQkyJYtHIoSbŒg~ fwhœRtCR„Rwœfœ¹u¡Ï’£Ýp«OorFkb@J_XUDVM+aa6D‚B2`K58=I1'GJ+IW;AW::J6/32-)(J7MP#@D/B)&E,<@$HO*N@"=I*BV+@O/>B8>F/@=!EB#\`+jk3Pn<3Q@4H-@B'\R'co+?x2SM=TX/GoTMcHDR1AM4VQ5pk6_jDFODCG16O0>?-:O#cP)ˆu=`£d6…iCP6GM'9g?6A9-B",9*+00263H<\g(ik6A‡K`XCti,`ŽcYrLUF*bY/^_4PrDCh:Ib4EI(TB*OP,]_3Xo9D|CKW*KL0Kd=QL9~Y.T–V\[Jhi=nsPK‚YYk8Rarp=RgF[m6J|FBf9HO#Nb(Tn.Pj1RU;VU6W€B[{?NvC¾a-gw>JpE`+bK2zj1‹`I©‚K£È{†ê¨Hž‹q_0~q2–†VŰn¯÷¡U¨’DVAuv1y³ZO|N\W.UV,3rP.@%:@nR&‡X/_eGcO0W>.bB/Zf1\O0iF1sB+{†V¥xm¨p™sP|µi¹ŒY­Va…`i–`a¢gn}TuFQ„SiA-·xDA©ŸS?7]K,MQ/XS>WaDdP’‡;•ªw›t‚fË{J‚zF˜zFg¸n^qD>E'I@BB#Ÿ?$ˆÔˆ³©mÇã¯ËŒ†Ã‡¬ÌqƒžerŒW‡­eœ´||Àj¦jÁ†[jÊŸy£dz®etÂ}xO^PZm/¯ŽQÿÑ—uÍœ‚]AnV8yRB‡qT¿cW”Žqœa~˜Xzšd™ p\¾všs8ˆl…z[‘É’u]7V„;]o8§‚^‰€i§y`É”jÏœdŠ«Zm–[Y~LNP?NX5d[B¹rT™yižÙ~à݆ÿ¥€^]¯bO“9qt5|Pcd<€g0„oUv‘b’œg†jP¨“m›omnH¤[M…nLul=€¡hwwQ][;`oF€š_ªº}¢Áƒ‡Ÿfƒ‘^zRqxUh{^YwRUxLq\ªÐˆ]˜WY„M‚ˆTpsKo‡Hy†OŽ€Q…N¨…Mqi8Vh6v~M‹ akuGWa@xwP¬e[|CpŠLŒ”Zžl™®|˜­t®ÁtuI¿ŠjÄ z´¸ˆ­Æv„À|½Ó‰µ{p®mXƒG_šR‰•[m—?s}An…C–Sÿë‡ËÚcϯTVj.ON*YK(ej4ju7hz<„YV‡CguMfŠIvUvP‰{P„Žc€‘Rik>kT9R`3FZ:[bN££¦Ç|q³_³q¤Ètš†I’bGk_=zb=umBhz]¸§±n…ŠVŸdžï“–ø„ ÊsˆU„„_x›c_…`a“p²…«¾’ÂäœÉê¥Þ׋´o·¦‚®³g†yKmD{P|mKp[Gr]Fs€_”ªu|¨rl¨q€ e€¦_s•S€”nžžgŽ¥[cœPK„8Yc1WP>tvC^ƒ@fƒ<`‰CZŒBGh9MoHXƒGNr>XsMd“jƒµyŠ| Å”µÈÄ•kŽ^?WK@€yc†º„™Õš³à³´ã£»â—”Ówtš]q”o{¢|‡¥y¥swšj€ \Z‰=JmBQgHlsQlvJn|Ig}A[sFqn°Ÿjˆ‹G\k7TX7YbIr€€É§šÑ|zšKf†FW{H~}Q™…L’‹Ru™MWz7J`3QS2dX-XN2YU:YeXo¤gx©ko ~}«ƒ¶²rz¯xy¦j{Ÿidžfi–j€¬—ɯ׉¥¼\lm>VR;Q];W]5RM5OR5LW38K'/B2BL9_K;G`@&oF<7=@E+6I,NG-$K5+1:7:"3$ $445?GTI^I!BO.CP46B8?B-9<(V<#Mg+^\8B`8:T7@O+NT,Qh:Pi4<^-OL2]U-I{SC`LNP.S^4em=[eL7TAA5,>C'=Q-DJ.[^,{z8Œ¤[a›n8YIDN5EU'H\1CV29O8XO4CT1?@5F(Ìt7ºamªxiŽjx‘ZI§kYvns{F^zHQgBnn>qt:w€QŠUXšRZ{WJi:AO95M.CF+B5;Q$AO(,I,)1$&2.+64W6Zf+WtFCƒQiU9KBEcJVJ+^g3YŽBF}OC^E;N2KE(LP)Ja73V6CR0IR#HD-RZ%RV3E@g=Wc.žs1§™P:°™IWGJU+oP5†…L™•_`–_]Š[|DSBDlB7n>tH*Uo7;XILG&]Z!nb>\j;EP0Z;&qE(^rˆvAmˆaV‹`eu78{R:4%žC!™¤xR›WUE~^=žƒk•¯u«Šy‘nØ–H¦Šutuct}[ftYšŠIh²mKjS;Q,/S-);\:‘TebT’_9¡ŽIu‘Mmh8dg3~T‘ºkœ•^®Ð~…Æ‚¸¥s–þ¹Œ¢mŒT€¯fvœX^u;fk,”`ô†“¸}›¤{d›yXxŒjwT„Rƒ–Y~dx›p¯€i‹«€z‡Oˆ Yšœbuªtg~:aa>•b?’|`±nX¿ž{¿§o™r°’h|~^}”`uˆU‚tNvˆUà|g›zh€Î…ßÑqÌÿ©³Ù•ì’wć¬mÀøe´ib_.Šf@j]Jf_F‰h½„Y‡ƒI‡xOevJadDQvCzƒY¬¹•Ö‘‘¸t¡pR]”cDs‚X¤|X_€UV`9tE?kZEfŒa…„cŒ­ZzXzŠS‡dBP`:iW:€Nuh;vF¬•\ei9ˆ„Ky‰To_9]=*cP3[P,…yInˆS}¬et§c¬§oz‹E­hG¤Áyy~Y³­}‹›[“’x⣋ԋ“Ƀy»s©Xo˜N‘¯l{XkKk}4hi2zsAäv=‘T*‡[3gƒ:nlQ{ecx>oƒA¯š`”W€U¥ˆj‰[]U;`hH†Œk~zQisGfp@Vf9m];‰t…Æi©`‹”T•½„³ÍŒy@hQ5rW:xQ9im=svC|uKˆcAxY@xk?l]:¸Š€ÂÑŒœµh©‹e¤‚f¶‘jÄÁ±·l•‘f«g·]¾™c•{HQQ*<7*Y;3a?9jRA}xK`zEeX>gK5}vZ”œ}‘®Œµz~ `jNHc9aqS‚Sy•]|¨f~¸bV}Mm†Yj›d‹™\hšcu±k€¤hTIId>Z[@hrNgXz§„³Ü©¶ü·Åù°·ºy±kUpYInVAcQF‹€h¦¾—²Õš²Ð“¬¹r•žcx‘Vkb}œu} oƒ–jpa~TfŒL_„UZnNioZ}Kcc5ak@TqDdwRuiQ~bHg\6PZ<(X>!J\(AX<@P3FO*IP)Vf4GtCJf>Ca'LP1VO.:pQA]JTQ$mg-awI8iOHP#_R-„[+—m6tEaˆR:}U4JF3L#,D*)?%/8"B.8M&2M,+5&(3&..!%3//R:b['[}LW‡Q^r@5‡?=TDUN1za6gŠC:ŠQ2R{vMVpMH_EV]7IR6Gf5O]+bl39f$]P*nxHu˜O_£QMƒOcm;x~Es¢o„Vަbg€\q„Ph³w=DDPR(a^&m|IMwJgE&ˆ™S6£Œ]O4–V,ž“j›ž‘Öi“§‚‘©€šj_sRFƒmBk9¦\A¬nW}~X‡…U€Q?‰fM`/;j98I'E<&~A%CsLnQ5rœZRpN[p6–~=²¨j‰½{Ž€IšwMpZ»[Žù¶~wNmD¡±yž _RŒPPm'ˆk8¶˜\ÈÌÕÀ¬µ‹ ›i¡\™}Šf…ƒUjMŽqG‰qV¤{\…`‡‡C—”hŒŽR‚C¦bDš‚QÉœlò²…ô¦„Ú­Å´‰¼ªš¦Œ—ƒvŽ·†µ‡–{fŽga—pR­–]–ë‡ÕÙnÃÿŸÒî–ÀÿÑÎÿÁÙÿ¶eïŠK|D}xJ„’mªŠdu‚PxPbQwG-€nEesGkP– hœ¶x‹™e`fAtrOovLvb>t‰L‡_ElŽ^iwPnkNr}JccHaX=€—UƒeEuzSg|LŒ‚X|Œ]zlGjl7l[7xE[v6xI{O^b@}R5{]Ae];pmDc¤T“¬m“©cn¦Zas8Ts.~^°˜o¬·hja;’¡{±ò¥¡Ó‘žÅŒ…¿vqnKa_={r?†VržT_„=\`8llDEa8[M3mo=d€CvY•®nb…;`tCcyF¤|YŠ…TusE~mQ…²sƒ¡d„…O{vJ{^E~glNv…PhxGUV+H;)QE.]N9u_EshCsM–‚`®{‚…]œŠevhIYB4`B6xXBdtJ[mHQLf•Ru¤j²n†™\|c‚“Yt|Db|Dco=YbHnx[pXZp;`V7q\Lˆq_‹¹Ú´Ú…‚}IpHB~ODvU:ET*1K+YSD†iR†xOn]0MA=oT[jNzw\ten—`q€QovC_Lp“gs—hz iv€RcbFbqC^uEmvI{pJ}qJZk>W_Zqއ¡«…¸šj•Thh/Qb*Su<^›r~Øš§ü¥ªÝts@i[6eV1\M(=J-GV5?T8Ghb€³j}¡VdˆPdYh—bpšn{¡v}­ˆ’¼£«Ó¶¶Ø¢Ÿ¹t…¡s•«wŒ¢]b{S^mRqCRqUY†\s…GR\3On7_WNA=V75U:%@3(-'--2#;#'5$<5>M"@O+FQ.OK7OT1[@+VC0HW8KhMPH6JR0XT,ae,Rs9:r>Oa=ozH~‚FŽ`Z—iEpWNU>hY3T†<@|XBQ5@L6mV3œQW¤slT<}|GZrSg~O¥ŠEj¥ivvSvy@r‡Jg’MKLgZ=giHj&@cV\!_b*=pSAR*T:#}T-vvH_¨kS€DVo0?n+4[(KM"IK)_J#Gf6SV+Ss7R^)Z`8wvD{m@y£Y‚—VSŠQb\3x•UiŸuw¡_YE}qC•²q­Äzo§„ˆtU^…]OQ33c(b<½…< ºu_¨l]K™’K†Z¢§x‚€fzG=bO=cP3UM4ƒf0‡\8{yFx‘aU{S~Z5R¦V\lAAg>?I'C*UW5Kn@‡’Az‡XbdfœOs{I“­bxÃp•Ô„¶É”¨¸ƒ¹£x“ÿ¼¤dÛÓ›¶‰MŠNQp:`i)—`D«Š]ÉkþÚŸ‚˜uÐ{K¥ŠY““c½¤eqZzhC§xO•¡|¿¹€`›hœy;ˆµn„‰N—‹_ägVá‰Z¶ŒY¢ŸZ°©xÈ¡xÁ£iÛ¿~ÕΕÇΩҹ˜ÒïÄæã©pwev€U­†QžòŒ­å|ÐîÀÿ¡úÿ»ñÿÊØÿŘíd”Xki8|qWœ‹rq¨s¯vq}Gdl;`u>U‰OPe=Œll‘_r[—ƒUXeE¨Y>upSjT:yM]o:Sxb‰¹Ž°ÞšÅѾš_˜m@qK0\J0oS6SW1>U6@Z@Nl`‡¥i†µqtÊni®\d’Td‹^kft—o§„˜·œÁ‰’²uz™i~¥p‘§`lwQkqJm{O^tNGlT`yWa†NJq:9M6NH3LG0RO6AY8H]?ZT@Bh>.bE#>3)"M,?B(BJ/FY9T[:\T/VN4XMCDIAXF8UO/T?-fL2LY;YJ3IO&RB)RF.hcDOqN:F@K@3VN+Q_?8PJ"Rk*Wt3Vn1]p;vp4d8Mt:Ha/IK-cP$L‚;4‘N?\Io=ER:Mf;[gC\{SRdM>]6AL8}R-D’ZIV7Db*>d2CT*?Z3Lb2Dd5OV8Wh@eoAo’L]”Q[qNzƒImŽ[_ySTvNEd:Dj%?`(PZ*a]1QtMCc;Xg4LL5n_,j¡I<‡pL^/Jd1Kn.Nd;;g8GB.Lf/Xw=Qt9dq5lZ4fqq€Jˆ‡h`iNI}Y;]B¥Q*Z–a>[30U)YF/gJ/oŒKp¸Rk’?‹ŽTs²o‰Óz¯ß–ŸufV’a@†“fwtW~©a|§nW‰Lƒ„L|˜SewE—“Vw˜O¶|@®£¬´w¬­TVa4Um5V("h>&`J3ZaDDmIOHHT<2\G1RM?QGDJH5PQ8GI7_I.TR5qU?Dh=B>3;B(;E+4U$=G'?S&L'T[1VT-]V1Zt9DzHGa+SO!JN([Q,Z}DZ`Gzr8KVbi3€„=M™jE‚KInFMr8Nu5Me;\k5˜–bt’rl€IfƒSƒ{Ga]Fp‡VnWHtGqo2K†Fic.„‘SyÎux‰N•Íw£½~”Ž[‡˜suϵTŸB „…tSGp\Ë™fÿ­t9POEJ-3F+IL-_m0xG±A²Ðƒ¼Ïƒ™¤u‰°x‰“]˜©}u‘k^ZOtYmwL ŒHª¦gr‚M\€N¨‚Lü¬u¼lÀ°·ŸˆZpH]Q+/F%)+55AI(9W*Hc4pC‘I¨…E™wHS‚CHf8fsEÔ‚[ÉßÒõœåÿ­ôÿó¾ÿÌvÔ€fBNx;ÃyQª£t‹lCja1žcei?xId\~ºy„¹}Á„Þœ—äŸ~Âx•[[s@EG,UB(ØzP¿»u^”KKN-qsIX“Mrw:bV2‹_=’Yxd9[d1\~B{†Oy¤e¼—fƒ™^å|Yžp‘£µ”{Ë©~“¨bjŒNuƒOgƒFiu6qt8Zi­VCËb[©ƒk­¡p‰Š[Ї}ÿþìÿÖg£yM‚lM‰eJrCg|O[gCY]A[`BfzX~ªk˜½xƒ›n“n£¬b†”Z}‚OtˆDqpHxa{OUs?^}EG^0P\AKq5T`+[q1X^4Uc?\n6Up;U}>Lg.CM1EW@FbMPx]TtHUdP{pi›…›¼†¡Ä¥ÂްգÌì±³Ðyw‘Vch1=F!.0/1'GIJ}r¯v”¶w’·v†´io¡D6H(D]-Rq/;N$BF(M>7kaN{vKzzXŠZ‹„KtsDz{Vs‰On?ofI€sJw†Fq”JiŽK^~\u†N‚–Nm€Tm‚Qmx@e^:aZ/WS'F[4`sBRzRc•WpšSoše{¯ŒªÙ“¤Éhpˆ?Vf5QX-7=*JA3WZ>[wG\{Nd|YpˆNatEXhEVnU~Œh“‘c‡‹WZxMQv^y~TJZITLBFQ?9D;O<6QJ0SZ:-O=77;J>+U8$h=,gS0PsG>aUGA>R91LB6N>:F@@M>3N@3SI3WJ0zQ7‚X@TP=fKWX1Pa,EA8VF1Wv6L‰X@bSAQ:NW35V58<*_F i`.=ZPSOWv'No*K]2>R,-E#9:3M#58!>;#IE"8O3RP3‰\+šCWÐwRŒzVgAie6]…@EnMLD3ZB$CA$J:(dT/s{>lsH>xC5Y;@K2JW(UF1AK6PU7[_3of6`ˆFp†]Ž„Nd‡btpKmn<‡„DdtQaOJa^1}ƒIb‰UlU9QiWcQbKa|I]IQ}H^‡Mvš_‚˜Zw£]~‘TpŽPQ–UO|O9|J6g:HT1LZ0Ac/FT%SR(JX-VK.Cx:>O8TS"De*Jh&ui.b”Sj„TIa`zCm„DswAnˆIe‘W‡¬\g³|Mˆ_FW-\p4z…E†žSrÈ~zšUiŸaacM`5[d6‰žSRVXål6tZ;hLE:-_6‡ƒ8¸s¡­z{ŒfF’rfkFÆlC‚“]v[yuH«|FȺ|e¢Šgwaœ‘g~–w}ª]ª‹Ij¢Fp¢NšÁX²Õ~¬°yzÂci‚]nvGs–Lºç„ܛׄqeE_T,ac>j?è}Vßµ™¿Ý¹ Ë£¶»ˆ¸±{vmPƒxKcˆSVeEXzJmt9]fKˆx:¦Àp§¥rÉ‚b²´…¬wYž|J¥g±·|–ŠnoŒU’ŸX°‘n™§mtœbp<ÂvBº{U¹¾‡‰±z™¸zr·yUJOwHe€H{•Mo˜Tv¡Xf›_NnPIc=?m5TG$dd?oŽXžQްG¬£ZÌéÿÿ¨ºÿ¿R¬bD8"Ul8¤l2[h2a[.Zu-Œu-g…=¨§mŒÇ|™©b “aµÙ“¼¸’ÁÁ˜‹º‘”_ak1a](Hc/nv=‘¶lb‘WU€H}‹X\…ESo3UM+}{Ld_6n\:y„Q’’\Ф_•¥S•{ExS̃Ӝ†‰œi–sOžŠT”•R‡¤a{Œ\|•if£_v«Xœ\ ŠN ŠG“OQ–v?x>rR0qS([\.©wm¦ÿ¹ƒÊ€dB\€9PƒGRŒI¥Œ`”Ìmg‰>’›awº`x¢Fw…AƒƒU ”e¹Ÿ|¿¥{ЇO~Fd|Qj–\xCov2hq6‹—f’Áj‘Vo‹L”²^u‡Lv…Wa‚\XhT’}ôåŽÆŠ\˜‰f³°mšŽ[thBšaIºvI™—Sv‚Mfn>RmBA(MK,I:+`T9n}Mi|e“`ƒJ`pAamJhƒJaoAF@DI8RJ+oM3o];DPJQV>G3PC=HR5HM=KK;LG:FK;SL9\S6md8›`?\ƒKLlUMiAFj=B[3BP4?V)9^/CS(JP"HZ+He8nV5¯\(¢…Ef–\U†izxW›VW¢xO}mCtA?jDMc?jcCq}KD‡aC]RIP7JR;D`?K\?E\->C)iG/Šo-Kª^Frs]a8Fk>0C@@? QHgX,TxFQ|NBl00H%20445=:K 0M+;1$8:#<6<@!AV*US(‹W0}L4Mf5Be@JS0IM&FE(EG,9P0hH4pp:O[F_g@_j;mp5nHo€MSiEJ[0dY.qx8x™Zv¬omª{[ªid|KT€KVfHSX8Rd?R}L>k@;T'CT%U\$BW/IH,Ok+9f@Db-Dw“d?–§YY¹|Z–_\¨UZƒR„f?…šPx«jljI…ZlK7’kIN¢~`eJŠL`cP„L3J~_SoGˆŠ;–]‹_R—dDƒSigLX\<[h>T^4^ƒBž‹^¿›aǺz|ŠcyŠ\Œ¦Yt¤^]‰Eer3nq:mS0jN(UM&ƒ[2c—L_~Aº¹\°ÕuªÅvP‹]XR2gR0vŠNKuH‡l4„„OžŒ]~ÁǦf± az—evX…‰VmdT–Z©n5ƒuS«´_Š·vr\¢g@T)rH…w<‰‰@u‹@ÜqN¶êŠ­ÆWR¥EV\7qAX9a³NRu/_z3m‘Ov”X— gw™[`rAkA”Ñ’aR*fT*‚d8ŒcBbCvJfaœØ…¨Þ—_¡``P.ŒŒ\W†Fj}?_„LkqF‘–Yv¬Xžšc‰¦a{}Pxc:iS9—mO›TH—aO²ÀƒŠºhqŠGxŽRƒˆT…œ`‰Œ\r†Mˆ•PŒAlt;d…E–l›ã¤Z}RZrQS™XJg4DC*ŠiaÛÿ³³db¡Wi—R{˜H™S7_w;—™avÈmL”N[•Dv~K“†P®Œeã´Š™³o€Ei{?sd{¥t}”QYf'fu%–“L§¡h¨Qz‡Oƒ®itÇwr«h–®u™ºy¿ÑšÅ«h‡dEŠ_DlBijEdK|hNzzBŒtLŒqOnpIˆnGnS‡ŒjŸ™uƒ‹ZŽ„u½¢z¡•\¦™X¹ƒO¨€Qˆ¤nºÊy§ž[—wDuQ´˜e›­qŒ›bob²}k‰†]ššbx„Mt‚HmsJ‹‚SmuR|›‡¯¨m~ˆLmŠZ£ml“KRT7QaGx“u§¥×˜~®]Zq6J]5TK/II3^^J[nZ[bH]WEfVFu_Mmažr•b…†_ŽtWu†ZYmJY\QmlObeMGD)-/3+<<;sƒe—¦‡¬ÂztŒ=Xj4Y{Jkƒ`t•^d‹H@\0@G4^iDqŠC_Y…¤Z~™JwGdEWj7PR)QQ-VX=r\eŒ‚\o„OfBXk@lk@gq>Vh1MU+ED8DU8Sa`Œd‰qImwIe‡av§•ƦÃk‹ŸDGU$5D(3I/7Y@L^A?Z;Wj6Qc5Rc2DV-AU$+J%0F7LsJI‚OMuSXu\w†UbOB_YFThMTjNPaLJ^KZTEG[FXG?^L6dW9tmE_gHA]KcPGZd:RmBUU?TC:\H9XLM,BW%FE(@H)\Q.ZZ,wZ<¯^.²yEªšbŽšjj„o\t\deEdiq75[.2J(1G"0C.CJ0J[)2k985/*81=3?7?!4:$FK%†C"ˆv2MÐM†~g`B^g=A|M/[C4?.;7(X:%Ln=>\BIP*RR28a>A?*hC#pm:@nKS]i;7J!Èp«z`–]hlMk]:q†Nxšob€[lcD™a¡ž}è’ds¿‚n™T£·v‚¡o`ŠPa„G`T=f{G¨Rx¤VRK„xB[xGZrNO@µvNâ©€²’‡¢mŒ¹vg~RAm76)L80[(51795?!aN)e~:t–F‰ÁdªwG‚ˆca€Qmi5zL.~‹F>a:rg6r«Y¨áޱ€z¥hpShb5yLƒ£f–l\«nSÙÚœ£å¢czc„ZD™wfrNq^QŒ\‡iP«“_—¤]œÊ•ˆŒY‰TA’ƒ^kŠJJa0ob6Ík…s_›—u–” ¼–†í¢‘ࣆʋ…”hƒ˜[_j‰L†’UÚ¾iÑÿµ¨üµG°})j<<1KC$UZ$Tq2bv:tZ2i¨G|Y†¥`bÇ\‡†@RŒCt€<`i5{wHu†UrkD]g@Xk>²Æ„q¹y]¯vh¢dp”Yl…T†¤r¦Õƒ¨É‡˜§bC^6?C#^U-Vx5Œ¥pi§fŠyM‹Q‘™V‰‚E©‘U‰Ly‚ThdowBSt9ohEyœhŒ¶yÕÆ‹¨Ó‡¢µzµá¥hÈ‹ZšY…€IäáœSIqX>œ•Y„“Lf•C]u?v”S²¸eƒ¢GzœMz“L‚k9–n?zmD¨‚aެchŽMWwAx‹\Œ£hVp6Qm>Zq"]~)‹wFs|MujH‰”i¯Å‚¿r—™\”|NŸ{c‡Š[{Q‘PvjDwhO–€`®‚U{ƒA}sQu~IyOFvzRtlG¢`Š`‘f˯°Ì܃‹‹KzhBsj;E–dî™h“Nri8toAƒtS‡pT–cLb`¹vcœlU’wc¡[}„N€ƒW…‰Zm‡jÙ¦€¶“Uh‚IqˆS{ŒN_X8SL>vfNƒ§ˆ³ÇŸ½Ý¤¡Ô…o°`a=@T-?K(=F5S\?U_GE56E89]GVsRw›p›ªayy?Xw>e„Ul‰Mi~Jl‚Nv@ny6[h/HhFgyDl[3X[.QRBrvOr‡Jaq;bb4OK.`JM@@=@.A3,V@+aa0Qy=DzEEjJ;\99M.><(gF)Ag9RP>^I.mK.wG.k_0Qk:Hf=EQ0Q=)HA%IB2TP6Yd5Jh=NV=[_:K_?4N6,D+'6-#:;P22K29A%eU#^>^_Gbh7H^APE5@[+YG2kD jzKeK[ŒVN?œ‹@v“_a{KZqD?]CAU&FZ)3L4FO&G[-EV5^z7ylJd˜Oy]Hm‹J9Žy@L5[C9Q0rBk_02€IFQ(L[#ic.4ƒG-D'G?OL"Db9OS.Lq17j„†;b™\Ÿh–žu•ž{“¥‰u²Epid;9iFcZ>TfAdiI˜£XÈ´B Âb€œIfx4dp?BV#^`-hq:‚hBfzHcScd«Ÿo›ºy¥ÎÐŒ’¿‡Ã€œ°q¢˜chTqŽLœJi†@`‚7if>^qE€‚HrI„I—­hp…>Wn6Ob(`f2Qk4lqCZ],R~0\m<¦t\l‘\i‹S‡‡YˆMa^>DY@[aX– }Á½ˆ¹¨a’{^™`›xY||FkvAvgIqnBYP:gXF{zIˆaK“€_pü´‰Ú†OpOq|BmzB‘L•yFrhD}mNrs6e[3gJ2sR<~^U‘jOŒ]?xUCqnTŒzNxtI€[­‘d®kµœt©¡w“¥\g‡PiŠ]g‘ai…MnƒcŒ©±¾„³Ñ“¸Õ™›Õ•Œ±[euiu8hn2bg6Kk@b‡Jkt?UY5[kAgrA€|AtQ7qO5`U1IN/IS8SY?b^C\eDLX6?A2NZ@aaETdJ[iCXiKrlBVI*>C1ES=]ya¼Žž¾eorH`ZEY\=RXHgcgƒ‘v¨§d‘k0H=0N_;`€?Os?CgCnhGbhFadPmgKeoCL`@DX7t?.pK9NOGWKKZTS50r?%R`6>JD(>3',":W/aU*\e=Vr;G~F=mFLR7pS,Rc;RLE2H3<:.Y<%kQ&[c54uK2OA;3!A>&EG0FS3NQ.>Z+BG5;J/;I0BL37X:BY5CX)HX3WV6xc7M•B1rN?G3bW&ix’cIKEVI,Cn?3fL/J7$J407.I6=G8ET/Oa:?\5OJ7]X)Ic5N_Gd\;np=<ŸHUfMzg@L{A9[9MG'HI#5<%Z=)ˆt1@˜mKQIXW4\fFgFNe/EgA\j;eƒQoŽNgXW|MJfJ;Y?AQ6o[%dZ7t;@kIu~As³RZUXf?Wb7:`1=O,Lr/iEj“POS^S8PA!RK/}s5[º/|q#?0)0,84;AN!\T$}•F:ˆd4C&/APD$Q„D?jQ?U)DQ,4J)AR*bl1>nGDP.XtCmmD;¢n=E6KCSd'FR,?a1Q\1hX2ntFjƒTˆ™iL†hbdF’O”kJŒ]{qR’xKZ©kj|QuG\˜fdr8uh@ƒcC`o?ÍN/œ’[zgNcP:Pa8eo@bqš\C¶žl´Ô£rÄ ]xe`Jci=x@lM|kMŠ“A«×ÈÖŽ÷ÿʈÿÐ[“fhF ‚e©·z–¯qOŸs>gK¢cDÆ€€”{w¹‚°d¹°–ñ‰x•œzmEkmL°¨uÍ•tqø¬_fByd4Œlº–„‘—qÿ»ÈôŸµŒ¢¾ ­¾£™¶£ˆ¨xQ_/˜rPcLg¸Š€dI{^Ozf:Ö|[âÆ©®‚œŒ_½ v¬Ø•x¢txŒXº“L€‹V|^=pdArWH‹eYˆ¥†§in¤WjNVGWz9qŠTQz:^0‡ˆR\zP\d.an+kDdvBJ„Dgz5™•E‚H›²d”º{’·|›°w¼q…¢T‚¨f|š]x”TtQZY6s]E‰uKKV~8}SŸ“d`œ\š¢e¬®i™„P|yS­“s£Ÿg‹„L}®d‹‘hˆ‚^’`P teÏï§j³kjR[O/[]4VM)D?%Ó¯“ÿÿӼ譸€_¼tCtEDH5š•’»ÿÑ–û™’¦tâÿ°¸¶}­pqOoµ_žN[h8aX0Lh.T@,}Z7Œa4\L'Š0"JN-]nB_{NRu7je9}sFl{M‚k“OX_1QC2^ST€cO„WGrdXmŒ®z}¨cqyQ{iLpcGnqLoxY_oBSl7Rm5VrDŽw[}—^–^x‘`ƒªz¥Ç”ǰʒ»È““Á‚k¨U`Ee„E\p>N[7OTW`MUaDIR5@H-5?*2EAV4=T0=\.7U%;D'38$..!3.!68"9B-CZ:JlS,770#)2(!3(!1.$21)D(s;)wd48{X.WZ868BK1LE-KJ*GT2H]:BO>HO2OH3TK65S54F5H@'VA"JB,T=,FD0@>.T;+cC1LT:DX?GF+L9VT0tT4bs?WwR6`A4G-26#10M6OX%/G4C4,8A#9D01?-47%BB)SJ&6cT9KY4Q`6Jc??e;Ei6Uy88h5RE-—T(W²UCŠ}Uf@W}J|€I”»Ym¹Š[“R`„WD|KFOEQm0/T:F4%UE&SR7VS`1e_1išDsXN˜W@`<=L)G8LF"¶k9zèžJž4vV3Q5)E28A"C!u[=on;tˆV‚¡j}wdŽn[h¨y¾ŠKr«houWw_>€Y=zF¢ZfÔMlE[BQZšT9®Z4lN:mc>oˆQp dY›ejUGY`BzŽ\™Äy—Ä‚’±€„°{r®‘ti„Nz¢\a‹C‘•U¤ªa”‰Xÿĵ¿®n¯x™d›·zfvMö§cwª~m•n…‡s°®ƒ¥Ý¥“ò¨“‡`Ѹ“¿è¿žr`ªuH{O²‚UÊtR•̓v`p¸’¸xYפ㿒ÿÌ—­`EîuYér`þƒ_šzYS_,}o:D:‹QAÃܘƒsJv~Fas5rDæaCÜzO––n½»ˆ¦©†Š®voŽtmhN‹eb'Da+X{EuŸf¡ªw†bbŒ[` cŸ’i¹£r€Y—pMÄzÞÝ®¬·’³î—‘Ð~¹¾‹®¸i–¶PxD{Ša]ŽsN¬ƒd¨cÅŸŠ—“]U¯sc¬r[i;V@+]?(Z=)^PN˜izmCgT:rO<•\KXCrLF{ZS¦nŸ«|ŸÊŠƒ²nx‚Nˆj@qkK…W€D[i8Wj?c~PŽ”x§Í€|ªc‚¨Zž{ºËš´Þ— Æƒ™¼·ß­ŸÌfy™]|ªf…³jz²`gœj{°ip“Lˆ®j¬çŸ¾ì}…ÂiŽÈw}Ìk]†I`]Hƒi[£u]½w]ž|S€cIqYN„]]¦xk¡že†™U¢m’¢k«ehŽW`‰Pr\}‹SpLluJ``9c`Zmž‘É‚h‰TNV9KC-@9>clhšÁy·fx¤QfGmxHRk?sjJ}hAhbPŒlcŸ‚WjkJ{XA\N=[ZJdyNj–t‰½†ƒ´¦Ÿ‹½ª›¿¸‡ÃŠ^£qQ—eG€dY”‚NT‚=Jl0:J%28):<%8F"(6 $60;]HMw]1W;3@<$1-'",7'0,D.b1 d\/MaQPhSMZC1]DCH4EG(LU+D]8;G4DH+IK+KN/@W23J1H7%JHSQ0_L2bX3lF7wO8kU=MH>=K9?L-_K)[_8~[\K>A89M(/R-7:$CF"4R,55->7 _D#?\/2RC<=,:G(G8)HL%<[?.;3!;+&2B2gI}f(oˆAVŽZ]|[i‚Mc‹NGwGJU5;j4:bC?O+VDwI%X}:MfWKL8He9bmJJwB7U8Ha4Ai>PY:Hj4Za:o|Bh¡PR>SZ0if=…s>y¾c¥xnb›_“ÑukÁ‹u‘_„šKišd`“oE‚LDcHLV;\gY55V)=E"ˆa%S«`2}_)J4.3oCW™GOdH8N19H)EW5U^5Og4Rg:HQ2P,z—^M’gPmHq_2BS6NW'brDc…Ydr\}“]EkW:0)„M0^ƒ`£rL¯]K‡VX]7VuI]q@qT/žy?u¹‚Y‰Ñ·ŒT}e‡^IŒsN„§r‡³™µx}´…w­{ˆ{_‡Æs‡Ðƒ~€‡Âyžµ‡²Ã}—Í©ª¥r†^°ŽKmÁQd<•]@ÌÖ„ª£vʸÆx~¨…}lGÉŸv¢Þ¢”¨r±Ì”¾¹’ÝÑ›¢ã ÞqSÿª€ÅÙ±™È޶“\kŒX…•Y‚•Y£Í‹«¨}ì˜e¹¼‰õ¿¡ÿÿäp•gs‰\uU´}^ŠoZJa9M…I«l=lcQ†sR¿ÁЉ…ZwˆT°¤d¦YŒGgŒSd|8÷“aά””›oߪ€²å¶ˆµ‡ÒÈ¢€_|`Jh_LÄÐ’ŸÙÃñ’|¾vr¨Z~°chŽWpT4”Š[‚™Rov@VŠTnG‚n@‡¦{…²jkŠ>l€:ÿ±„Óƒ £r¿ð½Áÿ 蟃¾€ptJesFxuS †n”˜g›xW›ŠGŠ¥^|•J¥—K¦±`†sE°…c”¤h¾•i’¥f}†Wy~L—\˜¿s­Šn·–…ÿÿàÏÒ’ Ìp]œJWo*Ss/VR,MX2l”GŠÇm·Ð~žÙ‰žÕ~¹é„è~¥Ï†ÿÿÄõÿœÊÿ¡Ôÿ§€êpƒµM{ŸD]’EgŽO\x:k|GewCViE‰ŽY–Ág’àul»`a`CuŒfcCHE0I]/Jc9Ij4Ad)]d1¥œnÓχÀžkÕe¹©o´°ŽÛ׉ÿÔŠ…mº{~ÿËž­uP©YC°…U÷¦}ÄΆyˆ_oiQ˜wWwj@_L9|OB’V?ÂUJ°Z>kWL”vXkLcu@NO;NC105I*3;.8/%;;%+C([4+\V(;[=MF=OT6uA8VD1X76K:/Q>4gQ1kc8]f>k`Er]>*mH/CG:+"H;NE&PB"CD.:B-N?*lH/PeB2WB.6:/-%60!?32O)47-)7#.6!::?DSI"rN$`r:TpSYaD\i?Dt>GY5TW2@sB@_DOZ6a\-PzXbBmiEkwF…mD“rNu_QhVG9G:?1+`J$`‚=BuGR\6‡s;r¦Nm¯kh˜eQtT8S?:L&G[/O](K`6`h@­šU°Ú‚•ÐŽµq•°^¬d|§Z’§TŽª\~³owÂqD­zYyXcyFWuAIP2@m1CI4EF/QY4›f9‡Ä[]§ˆ\…][uLZ}K6sD0G&?Bxg,n…R>‰^2F-/:.d: d”E;oNFG*PGKZ4L_-Be3Ep3F]/uh4V™YazGEuWPI0H@'hE$w|AP]>nk>c“dCLEK="pm>g}b§•WhœlU’Xr¢f³Ø‘cÌ­VT ‰O¥Ï‚‰šˆ€UŸ•L”«lbŒhÜoK}¸…o´k¨wožhœ`Œ¢q‡¹}Ž·~‰¿‡‘¾p¦f¾¸Z ³l‘±mŽ¢`®O]mVb`?•x\•ŸmãœfµÍ„¿šmbŠgŠuCÈ•s¬¶~Ãí¢|›w¸^DÚÛ‘lÃŽ_mLÎiGÿ~UÈþÅŒ°t}wD¥Q  aéà‘›Ì¤x}cÿŸ„ÿÿÿŠ¥s™Y™›bz_ÄnZ‘–iw>nµ}ÝyY¤r„‡m˶l¬€¥sFÀ„a—·Œ‡œ]„­}`Xÿ‡MÓ¿—“¸ ÔqꚀÿŽwó½‚l}I|‘j°“wÈë¬Äÿ¿Áû¡ Ô˜Ái|¸g›®pTT5PE,¤pf¥`‰©SLJ¤³prÓ—Ò©‡z¹…`ƒGcŠ<Ó™WÕÓ‚Áï”·‰ö²sÖÕ˜Ãè¡…´yvŠfišeš˜o«Ø€“\…–O•¢U‡¢^°Ñd³Çj´²^ «hž¶u—Áˆ¿s„«a¸•^˜ŽY–¢l½À†Æ¬{á”}ÿÿʹŕr‡Yc|IHj,_w.Xn0lnBt«b¥Òx¬ÖŒŸº€•žh¡Ÿe¤ÄXâ³Xÿ«fȵrÞÔ¿Ø€˜¶Sn™POY)p`ClšOaƒDq†T‚ƒ]‰”Y­P޲e£»qxGpuQŽž`lR4T]9Lc5Y~M]t;Hs2Ir.’Œdµ˜iœhŒ`š‘k¹×•ØÉ|æ­mÿŸ{Ý”ú¥j‹hMo`Qz£s‰®|ÃЀÀ¾i¾Œh€xSbcJ_SSkXW{latl]‰l^k^Ty~bƒlKifNo^HdS8ZM/dUFlU©p[Á|OsG“xC‰zM—–l¶Ä‰¬Òsp“B_H8zhWŒdˆ¤b|OdŠP‡ŠHcv@]GMz=7=!UA7†[z RxJ|†Lr’S’¨e” T›h”©hgGw‘Z‘¿z¬õ¡Ïÿ¸Ìÿ²¿ê–¯è¦Ò»î–¾ú‹®Ã‰¿×­¸Ù‡©^|a²ƒu¥‡o¦}b˜‰e†{Z{t]‘¤…›¸VYY'50&QI>lzPjŠPy”n}¦{±m{ h‰«h’¦_©t™¹€§Á€£µjx‰CV_2W[L¤}¤Úž²ï¡©Ý‰ˆ¦dnvE`dA`^Am[;XRAvYD_cIbmE^^CUO;QXAZvi¥xŽdœ}[yRqŠbŽUnƒM^o]wUrƒXaŒLZ‰LX€EVƒ@Y†EYƒBQw=Ai>QdHspSWI4k[=ZwI8rV#B5=T*0T8+D14B(A@(7R.ZA2TO3MhFXcDgcBFRB@3„D7e[.!jP")49%0:42%@<#DD#UH-|M7CuT5JU2>1)5*')#7&9@1H5)71-6!<4#,M*>9!I>ND$HI/KK-RO-Ck5JV.TY1Ph>FyJ@YB_X(Es6PPAl8KŠXHZKl`;g‡JCk]NS6V\/4{:LK2|^&]ŸDI’Uoc:ww=`|DdbESm1D{N‚\9wµOZ}g~Q1u~BnŒT[ŸVK}YTlGceDQjARcF[h:D^5BH:MC%5O,7G1YH#Tx/?b=TW0fp?x„B~“MU¯x;~e2X6@E'Q_}rO§|QšdLnfAœ§LŒÓ€r¢k`†R€‰W™¸o¹‚cœ‡mˆƒi“vYŸÚ’‘ˆfc}Xwb;¶…JÿÁ|²m…@u‡Eæ_ÿ¶„„Ηº~fÿÿæÂ«|ƒI pŽŠPˆœPÉ’NX~@¸Ty­fºŠZ­—p¡”cǘXc£h£w:¨yB¿œSÀ‡B³¯fn“I¤ŽHÀ¤hÎ¡ŠƒnÍ–_¿Ò‡wÁx©tP¨‰x·Ž‡ÇÃ}ÔÛ´Õ‹Òq”½h²iW\704EI%¬iƒ®ev‰KÕgž¾€¸ò£Í°ŒºÞ©e˜Ok>„>ˆ£M ¥W²Ÿl‚’f‰ŠX¨›[{‡]œ¬s…°{’—X™}J† cy¬Q‰Ó{­ÓƒÏêžÅá”¶Ù†Ž±f©ÏªÒˆ‹¶rŒ£bo®b|¢Z±¤b¶½po[™p]ÄØ•±…\¤‚Tx’YLl:_h.Rq3db3oS0˜_C™¥e‡œZo‡QezDŠGq˜BPq1lPFŸ¬e¬¯[|žS´iJ\Šam˜d†®l€¾n–¶dŠF|j9{wAixHidBkU3ƒ…_km;WZ=@%68/X[;S[+HW'GX%GR+hg9^r6Z‚N¡¡ax˜D[€Rš»™×ÿÒðÿÇÚÿ°¯Ü‡¢É{˜¶x¼ÂµÁ‘›²á¦µä’’Ãy‚³z¡¹—ÛÖ–¾«d¨h­«c¢h™½}‹¯GM{02W&9$LS:W{YoŸ„¯‡§b‘NxxGslBdeHƒˆ^’Êv‰³l€Ÿ`\ŠMVtEu‰j¥Â‘¶Ñ¤Â†£[u€A^oKnqPhtE^kMykQlqM^uJvw\{uHbkF^}e‹¢|©šd¦WŠShy[d„Q`ˆI]?Ru;Ts?Wl@SkJrNmLmŒIc‡KW†E[„F[{:Va3FG3H\GPI,|L.tX*Ne36ZJ,C-::(W@Jn3FZIIJ=GR9UQARZA\WApM:fuFwuaYPCpZiBH~I4fZ;]V>]XB`bCS`F1X;Z4(fC"O7224K=@^0A]BAaYf/D7-J*+=+42%I< 7V/7A?7I+3:));,86!ECE?*VQ.Bb7HI5B[-?_1?O-WQ3Nv@@qP`e>Ey?kR<`l5=O?Z<+‡[-MyJ;XSFN3W\0N€7IoBeg0w€9YŸQ`ŠQSyJES>GN%fF-Q…;™sFXÈeAoiGE2Wg:muAiCd’W\‹UQuQfjKNxCLbFXžV]IQgRWW:3sC4I3KN)v|6M˜]IlX~IExKB]4Hg8H[7ps0R…Lb\9rv9y†Md‰SbŸUNŠQ]ŒGs—]YhXAq>l:'hzI­‡S›Ø–°õ»¸é­£Ì“^‚XH\/EP*eX3‚ZC΋Q›ÓŠÏ‚}Åz“³¦nhŠU^…Id‘Qy™T”»q¡ÌŠÐÍ‘¾Œ£–e¶×yl±hdNr«M‹Äsm·t“O7lY7’bAi`Q€zI°å|™³ˆ¡Œpu™d¥rTaFcA+ºRF™˜„µ˜s®é²„‰\^€?t˜QŽš`ª¡pj mlŒFeh7”tDÜ”i}‘hÿ⤟‡jft=q…OpFƒŒZª‚fa˜]ˆ•[ϱŒ†¬~³’o¤É£ ·ŠÛÊ‘kÛvM‡™t¡‚‚Ÿ`w¥idqI\o7¡};¹˜e…›`¡¦[Ÿ]eT:–iNºˆxº•}¥›qŸÙ‘Ænˆ±[ŒŒ[RxS*> 2I$Pk4¦Wr†HRzJ§xT£ó´ÒÉ͸‚ËΜk–Vfˆdw3h_:kQ{kpĉ¯Á†ƒÀnì³u»ãœûß‘ÝïŸÅ÷˜˜é™³Ý–¤ÛŒŸ¾‹°ÉŽ’Í|Œ izX™˜e{¬Y®zY’¥ahZ>„sNv‹WLO+p`CdˆZIQ7>J*:2&ŒŠZªaa—KXyALq;Qg3Wk5tzO‹™M®ms¿N_Š8’l,‹ŽCn“>}ˆ>ŒLt±SV‘BTt@rfpeW…‰h{}Wz|S˜wP«ŽT…{NÈa…–iŒœ\Tw6Wd3^`2r{=e>Xx.H^+H_0Cb1\pBee8?T4>U6U`,A_(;Z+3O".K$9] =d(\t7o‹Gz”FhŽW±•Æè“ÅÑ®®v Á„‡±ov¦q­y™Â‹©Ñ£·Û–¨Ê’œÈ‡—Ĕő½Ó–¦Îp‚©e–¶a}¬k‘¿m®Tt£P[:Ap,<`6Upg†´‘˜µp}Vy‡TQ‡UY‚PmxNp€]—¯g‹»^в‡Êƒ€²hcŸh‡¿‹ŸÉ–—Ê„°ZeƒE]~a}d{“UiƒRkpYkmOwqO€iHsh=ZnJ_iªx…®\d‹D[rEdjWj|Hj‚Ds†9V^&9E)9D;L]Oh‚a{ [dž]hŸ^h“R\…CWm1?? *75:E&'G7 O4'i?/†dŒ{Gq…^uzcisZnLKyI7‡OT?;D-FA!L@$7Q9=<6?I,2A-::&6:![7"RZ+KsAGxCAiCEL7BV-LL)X]8]yJc}UO‹SXcJ4N217$L4rb+LrACQ9J]5V]R_5Xi8azBHr´eoŒ`{˜Wf‰V\J_c=|n;¸D‡—h‚¥[cšX]ŽEa•A{‚?k‰F{{Ge˜LJ‰QAcLFW05\6=C,\N,za;–ŠM¬›Z¹æŒQÀ‡]nNTnGnW6b„>\rF[rTUM48qDDB-KM"…s4`²fp‰VNnVGK4KU2QvED†E_kBdjA\‡G9c@XK+Y†:MiFTY.A]'GC(LJ%OY3Y[8S|Dvl;pUk¨eX£bVTm`I{·sÑÚ¢Ìÿº®Ë¨‘œtj†dS~O@a+[S2joCmbL†mFŒµlŠÌºq©Ùm¶‹ZUl¡Yt¯[‚¼n­p–Àv“̄ēŒ`Êhm™U–`¢˜[ŸÞŽnÿÑbz`kcBlY1^E/«¬L—Òˆ€˜ppgMmkF›@0T“vQ`A§h@ŽyYã¼{}Ô©b|LtoUu0cV,Q‚GFO2Pf?Qa7\€=d˜Dv—Mˆ›Sõ„»ß›†ÍnýtêÆÓ—_¼ƒS´„_Á£{®ò¡œÉ€²®uªÇ|w‹M•¤t”¬t”aŠ•[w‚Oa~D€pW™dœ‡`V–pQ„b?YdHTc71O1Q7#~X:®_l¥dr¨xm£tk¼r™—\¼}Ïú¢mšKJp+Cj)g@`Š1U~-ƒ‹Nºmo©_q•^u¦cu¨aš§f¦œct`Zxev†c¯s\}®jŠ¨Š¥Ò¤î✙Q`M1t<;Ÿƒb´å¦À÷«´è—¨ô“›Èuůc•O§pTÂ|R|¦RfŸ[˜c“|Z³±x¥¸oª§i”MƒeAwdU§‰o“x¾mŽŠd„ˆWl{QŠˆ_“ŠWumJ~o\—Œk–ˆaˆ˜nw˜X˜qS‘xSzY¨{]Æ›eft8Na2Me6Wb9am=Qp0Og4Oi7Q\5Qc4LM-gQ3_`=Oc0Dg-F[(;W+;X(?`+@e&B\!Oq%a„9q£Vª]¥¤ZƒXl§u Î‹´r‰¾‚–È’Ó©–Ø  Õ¨¡Ù¢¥×‘˜Å‚¡È¥Ò™²É‹ŽÃi{ª[rŸoŒ¿v“ÓiÅmz³VS6T‚=RcᄆŸUt‰\|ªz‰Ävw¬R^}Ih{\v¥u‚ƈ™á•µò—©Õƒƒ¼|޶—¬ßŸªÔŒ¡³gd“Rd‹sŒ¦mƒ¡`~ŒStuTnkLok=aZ4N_BR{Ti‹gy£i¤Uoˆ=Nj0K\2_R2\_5Uw/Gl02X46]FJum€Ê„˜ÖuŒÄwŽÏo{Å^k›QXz?-Q3@8'^<3&1:-1&I1!}D+ˆsF]‹]Wg`KOTDOEIK8?Z90PM30<>7(:F)NN0jQ3ao:qdEzdCwpG{dHojJ™ZI˜^BjL|_c…dZQVQ?AjC.…W9jlC]^VL[H6EB,4,RA&]b5Vc@f\8ƒ\3‚g>uŒMkºpym†gWigGOoTGpNehI>wJ9?A8>'8CN7BS)E[A7U;1F20<(D?(OK,MX+`Z2^„C@‰Q=mT;[@D;1VI,Yn>gpLU…L3lU6KC4@-tT)X‚D.^R82$G=RN'jd.E{A^X6€Š@n”XJ–]JcU@d=G_5[]2‚vE›²QRƃF_]MS1DY2FN3BZ1OO?…]'l—M;d>MOHC&KV;Sb0Al9GE+]^3Ur3VyOJ\“R[X_„QŒ}Rµa{«oyªaF¾z_|_F‚AUP&DyIUR>5cB;?'IS&Š|:Z¤^FRB<\,@E6n`2p—KY£bHhIIa)Nh6@[:NX.Tf09X5?L%?i96S$GI%G_2_R1Dk5YY-sˆQt™dˆš\‘½v¨×“¿æ§ÌðÀ‚¤„PI:v\*‹‘[WyW=d8UO*\c6XmFdhF¦xF~Û“‡´n”Èu~¬wqŸc‹¾g‹Îuw·m©i{³u¹wˆµmnjG¡”G„Çz}†N„†Cæ’WÂÿÍ\ɾYkD_c/zrG–ÑsާdX\Q_7@C&f?&Ôj>x«ktJ€sQÞÜ™bºaP9_U(_fFTK9lh@–º`Œ‰Q±Ïƒ…‹XqwG~R€ˆWV‘`­T9’[@}dZˆhuyIÿ¢sÿ¦‰·Ìž¤mPƒ„P ‡^“lœ‡T‡œk†BY`B]zI\q<‹‰PzTTƒIg~KŸW°ŒiZcN‚lMŽŒw°§ÂÒ¶¤¢z‰}WwyIcb=QM2;D(.- =F,l’Jj“DŒ©eü²uÁ_r¡NZ£c]a,pd/ys3ea5eX,eq6K†=gsCežYu¯ky¯e‰®a“â†wøn¢N¸²X×ò€Ôæ|¹m½Š`—…m€›l~žy“Šm©ŸpÍÒ‹“Ãl§Us}=SqCª±Š–Ђ›c‚¥V|ŸZv¤mÛìƒÖƒ¦sêåŸiµvn”UbqHeP7c^I\—ib¾€‰ g°vÏ÷ƣݜ³Ö•{­[ÈÅ©»ÿ¥d”YUTR‹GcžJ[v6Q†9]ƒC™d§²j« X„x@‡†J‹…V¤¶w»Ë{«¶n·«oɈ¢Ò¡ÊõÇçâªÉ‘XE<&:;#ZR6~ c²ñ›°ö¥¿ÿ½Ãÿª Üy˜—S©uI¨Š\roC{U8—’K›±k¤ÅŽä㣺ю¹¬t‡ªnƒ¬›­y¦­lŒyZ †\ƒ…]€mU|rLŠW¡›aš§d§¼u‘©nš¢f±‹n•]wˆTl\Á‹d€uRˆyX{ˆARon$GmLo"fy3sŠ4Un6f`Gvt¿…¥tŒº˜Ë´²â­¶Û¯Á椿ë²Ü‰–½r…¤| ·‡ µlŒ Xz’Rt™\‡ª]Š™Zž¯t˜Çu³^f¢g{£e‡¦miy:QSAzoiŸ®n¨OfšNeŸm}²†™Â†±¶r£®s«¸‚·ÐœÑ™ÆàŸ°Ík‡“Ej|Fexdwl”QrˆU{€WxoPja4MU7NoRe‡gu§es”_u‘R^~@Mn2>\,GU*ML(Pa-Mp5=g?QtWjŸ„Û—´Óy•Æ…Ö¬Æ||µ€r½{g¬jUo§]DI(,R/79/T>.WK2_D?YN;DdBJdGS]LaKCOSAPL@3J98B4CH0AL2DR8VR3PR1WM0WD6dS7KU9x<:}W3~aEo‰XOyaVWQfQ>oiFikO~eLmbKLgOEFDYP+FmA^QHlJ2UN6iJ9€W7´uN¥ÃoUÇ@erDD6[I+tb<[‘T>v`Fi?FZ@dY3gX*ic7djD\ŠHD’[:fTLK7W`0^xR^‚Q\zOB~MVcFz;:{P1M=08"F,OO!g_(D„B}mG^ŠKidQa=N›_Ns`\xKZt?shH™žHDÌŒ=TY:R(3C(JI*I^4GeG`e0er+Wl=6‡YGID6W7HK-Kl&Z\:OX9Wp:b†Do‡En‚Hm|IqYEON,LP9MN-[Y6gk@¢€Mg„XqmR“¦J]¢wZxY^{WU‘_NxMZ[3Js3JP/~b.bœO[ZlOs~Oz†Wu˜]p§i‹ž\r¤`tŠb’sUŒG{Õ|JÅWtZO{DT~U4gCME*lu1tŒNOŽRC`@D_1RZ=z„Q|Ÿgdš_D†SOP1Ms4JV0Dm5Jb=5U4T=$>rE:P8JR%Nb4Ga22Q*bT*w‘Wp‘g¤¹z±æ¨¾ßª¹¶”nqFk<<_2qU,mxOeuIMa:Vb=e\7tu=prL¥S;šYƒ¾Š…®gt˜hˆ¹k†Î†{¼xu g~™luX„Xt—}b‰o¥€T‹ô–kƒ`ko@zzE¾m=‹ÈT…YXFŸ¤a†ìc‰WGh5KZyƒd¿Ñ¨¬Ó™€Š[zUq¡Y¿Ÿråâ¬©àœ¶~ÂÔŒÈ䎖¾l‚’WYW>„\BÜÁ”ÿÿ¹¬ÿŽ‚²oõÛª¾þ¾³à–tœiöÖ§§Ü‹{·w¹~·f}¼ql«`p™O¡ˆi°‹U `1tZ5Xd9qf=~mF“n[—–e†‰P£a®µu¬±cªrJ´ˆ[lQ0?B/P|8s¢F³a£¸r®¼l¦L‘oBleD_yEdzJžpM”xBUL0\O2~hEº¬z´ z¼°‡¹¯˜À‹¢Þ°¸Ó–¼¿‡„™l€}_ƒq[ŽzYƒ‡_li} u—À‰—‘^rlJ€\OweKxhWy†SqkH”iW­ˆgˆ‡Qo{FnrI\pC\hAdnA`kAYh2Rf7YJYŒE_z7H])GF"+.-#5-:5!=@#?J(Gb3Hs6@s-=t.Tv-Tc-Cb%0>)Xadœµyr–v’¿ £Ï›½À‚ª´r±¨u±µm£´j¥kz e‡£e“³bq’BXx>]…Il’CLsCs›o¤±k—¸u•ºx–¦[u•bn|EAR9Oia“mvŽmh®dt§i‚²}ŒÁ¯yu¦cn•X—¢l©¿Œ²à™ Äca9Ia;XaW{r¥Tk–Ls\~Xwc:I_>HrVl‹h…¤cj‚EeyKcqAT_2?N-=C$19 6E(H`9NlO5CJ/FL7FJ7QY8WV:yi<Š~Jiˆf]u]uaK…XAwiKvqNoaWdOIPZHmT;ƒnbDRJC:*E:"VX3uh9`‚LNˆbQIJcM3l‰GS‹YZ\Z`‚>|¤[cWDjM8L-.P+@>!DR_P%^Ž:_SvpCd@=S2LS1Nb5FsBCY9NN(cX/P`5QqF>wQKZD_d,[v]jGŽfEioJo`Arj6wƒFk‰`„`†žhP‹b3C:CC#=R0GU#dg+`nApi:[ŸMXoWgf=oŠWuƒRw’V[†Qdq?Kc}¨h¢¤vÌÜ›±Ì¥­}ž“^m~fLa@I]BZX5ne6Z‚Lom7NvR[c.X[;[Q5qe8›E{Ï{oiŠŸS¨Þ–§è‹ùœ¨ÌzaÀƒEuDI.…mTŽ}[›|]ÁÛ‘sÎÀ\[9]€?‘iI€ˆbišVàØu¯¢ƒ‡âŒV³{P^?f{?kJsV›‹]ÿ›iˆÁ‹Âžo£Û«³‹ep¡W¢¦Qç¶pçĶä zq‹ŽQ‰Àm­a”·et¶o¦^Ÿ¨nq£o_Ÿtj¢sW‡arxP¬ŒVŸ·}n©ls~V’|`ŒuV|=¾‚Uˆ[x„J³¤z‡œ\ħbõ®‹§‹fÄGU~M~O™˜oŠ›z¡u‚²Š…§ˆ¬¥•€™^ŽhXqMMV<@Z?JI0Uh:ul>hi9}®tœR]H"KR![^6m‚QAG$vV%˜g0pU,~h5jˆ@o:Ò¼nžïšuÉoD“=Cr.—^¹Ö ¥úœTu`O(3F"7V4YyO~‡YzˆP€GY;s^WQe6=g:-{G;†D=hUI`Q@SPGŒT8€\8GHIIQ82?640.M.!>&~u?qkŽscY´a=‰jiHIk|>L|PU`=kr2SYWmHgg8XuBa\KtY9_xK…bN‹Z7m‚KA›f:TQRC0Na8PfCe`I>ˆS7bSdJ8c‰@C‡aifZ’¡J‚¾v>„f4J=BDB]"=Z)CX'n`.nŠGExT6Q91F+I<vU!m¡OSœq~ˆXœ¶V´Òrö¬nµzQ©i?[O`6Xh2??0E=H<(Rd.^k8jrW4CG*ML,Ms0Jk2S\.`d-SrAml=p…HrM~qE_mOegJmœXz’T”‰Hr¡aJpP3?.=2 LI)5M2LM.V`';Z9_Z.nr5%XV%^f:C]=[U-ˆ?R°fGi?@X%5U*E/!Le/ta“J]…P[MSV}M„–¯™hŒzY‚ƒN‘œ@k{Df“g~¯„œšh–y6ZU'So8oŠe•°}™®x“§kˆšOW[&/3#UJ/SgDdsLdq“«Žë¿pQiŠEt{5Vj1Ia0T^AI!,#15!3?!5>-?K4IS;E]9Bd9G[5=X0+F@oˆ„»Ý“§¿€x¨„†ÃŽ¡ÆµÅ‡‘«w—[qyFR:.-1'3,'6"*-1.J7(bE+R]=GnI4XG::@@A/S@)PS2[^@H]IMPKiX;gvFh‰`tƒfo‰mj–dY‡eNla=KDT82OA3RB<_J<NAhJEDN@LF<06&I%$KN&IYE6H;Q57m='›Q7l–Vƒ…€…|VU²ocˆmDxJHmGp]=¤t7R˜OQYLZf+Oh9WdCmX6i]?PxR`VG“M1mˆLK®r[’}azfqrOfŒYe…[YŽ`k^jZh‹fŠ…`¢¦[iªy/ed.H8CN&>d'BN#X_ iŠ?Qˆ[DUF6U4=V+I`1xf:€—Ru²m‰—v¸Ä]¿ô¥zã»vƒxht=TˆCP‹Jix8M}EF_RGQ;[X4V‚_Z/Lz;Mp=9b9F:'Qe6CR?Q_5qo7W“;T‚@g†4S‡9M}.bt(5u3UH.OQ+D|G?Z~pQV6Ô`8Åÿ¶l·µ˜ƒD§ŒLyxHgsEW;”¦Tl£rž˜Kw¿m@ˆhI?+~I-\M?_C/pe5–Œ_™trjHulCÍ’bÝ®Œ´|\>qrA_Z4RV6”V8dY=dY<ŒkP“htŒ] Pƒ¬r¥¾{е‰s_qqLmˆUg—m^vTOZ5OaNMd9ˆg?Hs7`X-‚z\¿ÿ²¾×‹}¶uX„HžQŒ´md¢mš¢T{xI}Y5of5¸oUàÅ·þ–lÒƒ„zVzO£˜_d‘jMuPJ^8–ƒR;Ÿ`?R)hiIH[@Ji9XV<[jGZm7‚€Hoœb/…HJ8)¨ŽsAxFcO:[rLru[ƒ¨oª™t´€ÄÈ‚ãÓ„ÅtÇx¢P´¨YÂÆvµÿ·˜ü¡\«WH.O<&IH7’h¡²|æù³ªý¿VŒ[€mCvŒKi–H‹\ Ê§Ï˜Íö¶ºôŸ„µoÂí¦²ÿºÝÿ¸éÿ°åÿ¼Òü¤ßÔ‚ì³ÃâžÅò¡Ùÿ©|±[޹b©Æ_¢Ñ`®S”¡Zˆ¨mœ½q”´j¦Ñy®ï–—ã—›ã˜|Ö„s³zœ¬ÿ·yŸqF„LwyK“•g·l¢’Q{pBuŠC—qCn^7m_H„¡h]¥n_œ^YšeT‰XnŽk}¨liŒS_`>YI,VB/VH8XaDfg=gd6ncDv}Qu’Q_€@Wg/ˆ}Q‰Tˆ|TbpDOkJV…`rµot²_Ž˜V‚¡|Š®¦o…•noaqv\s…ObmGcuFbfFŽ[Fƒ]HlaRƒtY’‡XsyElrT†Nl{Stx\iqKRhAQlCVzImŽ[q›gi td§|r«|£Ï“Ï~{Ð}Ù„e²WGg8\zEiub‰Švz¡x¯Ô˜Î퇫àv¢Úom«Q@~:4Y)0H(NR4b|Mr´‹×o§Ot›buÇ{i¸X_ƒ>WƒW™ ~À«nˆ?cd/co-Qh:fdM}dNYS06H(5Q*Gm/Og7ixY‹œl|¢csŸRL|;5Y4CW/G^6KQUgzv‹¡qŸ„W—pDk~AU4Om5HV2DM7NaF`‚F?X.*3!/7'6@2-;2EN2CP3JX=MlJKqHRv;El=_~e¤¸y”ªy…´‹¶}“±sŽŽeu€]z€b•…`.=04@/>:+):&<-1$'H%3D$+C.B.(]9"Qf<2dC2KK828M?,_P0TcBMKIXRCzkB„‘Ysš~„ƒ‰Ši…‘jcœpPpkLRHOF>MG=tA=zF9US?MAA=;.MN1-J,h+-lN'ejG7SC4=CF/-§9# ˆA†§ƒœum€£`\©w|u^hŠQ^‰qU`?3C1H7&G_#LQ.TU/Ua@mX?_i>qsU‚cBŸzWž¬s€ã c¤»eSf[aBR]HnV6g™Knz`efHqrM…ƒUUyZKlMAlA@mB8g6DP0v_#YOA|c`Q7`^'[q4a~Db€R…†XsžU’kφP¶ð…QÚ½?fqSI']h.Z€C_€GZoAErFOtH_uGJ{RFc=Fc:Hf9;b:=J.PX)Ko?TkEUr,Ot8OY/XP+‡[*_m4i_3c`=YO:YA,Œn<„®^e¢g`ƒKlw?Wƒ@l€=eŸ;O›NXz;_:?^0;\1K]9?D1@J#MA&\s1fmudA§†c¢ om“ZƒD»¥yÉ”nÍ¥z€Œbc¢±r‹“lQžwdpAƒ{Em|cŽ’qE‹YRV0¿lE½òª¦å¥„ÉŽW‡Dcp-op3o=š¥kY£yLaIUk?´€nÐœŠº€`ÇÁ‡†ÿщªtxˆX“{e‚—o^•bqj9i„GXn9—¨Xn²_Hg?QA9KOBNX2h„>]@\vF@Y8ÿvik“vdwt–xy‘mw‰d„H¨‹Q³Ãx–ŠPt‡G•‰L}£^gAj•?Ç®p²îu²lZ‚_c‰\V“_Œe†£i¿ºqί…Ûu}Ic‚?g’O|­s«Ì–ºÓ£Äý»®Ù¤‘̈µª|åã²ÜÿƸÿ£ãÿÁÂÿ¶®î‘êáÚÿ®ÄÓ–°æƒ—Q‚Kty7xj4_{Dy†V›¹v°Ït—Æi¥×‘ÊÿÀÐÿÃÈ랪΅š¿|§Ë•šÈvhIf_;\i?—xXŸ„_¡Ç‰ˆá‚… SŒƒQz‘F…~F„X‘¢b~žf–®g‘°{µ‚”®kzŸ[€§\h¦lh³td‰X]U7LV2Ta?VvE`\4k^hB¦S‹¾eoši“º—¦ï˜€»ou‡Tƒ}W~[{ŒVq‹Yl\j›mvšm}—tŒ«†‡²¥²ox’^q’jo’PesIarNbtP]sOSrKUnGh„Lp“_y¡l‹•`‚€aª³‘³Õ~§´mºÆu”—<=0C6!;J=oqˆ¥’³à©²Üsžµb±Ðg…ÀagŽVUƒJ@n.8Z3Pd‹Ã Ñuv¯RW…T£žx§¼_W‹BfrX’†T˜yI)Fa6Ne?txS‡‹I\i?Kc@Gl:9`/Wi>Za2EY+?X1QoNT€T^‹UTx>G^@mrMrh‹¶tŒ¶rЧ^czSfpXxzft™qKK/9A1A6,=@&-G-74)^/).H)$86E))U@$XJ6WP;,zm:uƒWiˆg^xhe`J|^HYxPV_UW?:WK8QO:NO;bC7RI9nR6Œj=±…P•—hÌo¢Ï„FÖ¾Co„AOCGN2wO.^ŒA>ŽPZHEne5W‰UMkQP`;H_7PY:InELoBum/MŠF9xWGV1kT%ug,mˆBr˜U^‹ZufHjL¥F©²QQÞ©2cn=A-NK*Se8Dk:S\2bm0_‚O]uSSuII|TOtJIvK3P?<:!KEHe5Le?Rf'Ps/Bd;LS-G\&CE/KO'0>'98$u\-y NsŠ^io@MxI_W2Y^1j‰D{‡Ho¨AU¤a1A5F(1L,E5:PW+ex5TˆRXJX}Emw4z„Sz˜[pŒja]ELQ8SX-Vr'Ty'T'R},K{"Ot)Io$ZF[r4KB=nHLX>kn>f R?xRR1!‚z9w­d¥k~»mË|œÔ—™ÍŒÅè¡Âܪw´Žz’`fŸca}UX„OMk=Yl2Ea9=VDGV6\X5s~Ax•]†ˆ[aœdS}YUyNg‘\XzOTP8AQ6;O2?1G7#[l-ICpp>Y”XxsAhf@…eBZ{T?i>YN,Žh2¬Y¸ne»~qœgV–Lr`2TT)X^1¥S‹ŠQs¯v^ f‡<3µ°a ´¿”g­¤†™sXÛיýž…hV…p5€hAq[NWFZW5|S2©Ÿn`b^eOcWnoEogPwBRlCNiWk‰\]ƒPJrHOlC_c?vh3TW#JU=]&Fc:j€Uq˜aoPIm<9`/WJ-AF5Y;3/D+?55pB.lnEt‡\UwlWPXP^?>N6Q62^F.cc@EsR4VJ=B,NH&NT1FL6X81Z9+a9,[O6[SD][I]eG>E=`E0iY%HmDHALg>2EX5hJD‡d;x‚YqhfVwQ`l]]gIZkJoE'@@-"3"D37Q$RB3YL%cI0HcD[TGzH4½f;¡zNàb½±e‚ÒŸL®œ?trPXC]R7amAS~CevOŒ€JM‘cInS@k>@Y:GY8DV4Kb7^p%R~A@oM=mEK]2hh1€JlŽ^g„VteFidCˆ€<ª³IPߟ;uw?\>:T4AO.=`/KX.h[$npC[|KTlD_`=`x;=kG4bG2T5DN)JX'Dl^?bC&Dh4Ff3^Z5Yo8hyPzŽAmªLD«Y;ŠG6o82V*FQ(LX/b_7^w>d‰BPFbg0ot8jzHqeDW‚MQlOOsFSz4Y{(V}0S€1W|,V~'Aw&Mg1XS3SpI2]V0r8oMs RCdBKW1›U5ˆf;L^4K\5]yCn}Ckr<£W€È˜F¦c;H2FI0rm5|±\mvUšŽbcÊ—eˆnÆ›‚‡Ù¬é¶“Ä× ²ŒuäÛ–³¦x]yEPq9(<"$2#!K20ggE[‰AN->G--K&%?#/2;>AtŽ£ÛòÑûÁx‡ŒGVz9YZ—¾†œÈgkBNx19O,[`U‹§dy©_y›Viy5M]'6T-Kc9T‰KX‘MOŠJ[•Hq“Lc”Mc}Ek~Qi}_rZj–UqˆNw‰L_„_c”s®Š•‡Œ®q¤iƒ¨aiˆSMdbjLsXsc~i„¡PYx6HY&FN8M 9W#=e8WmBcwSm…`j–VNvER\B{Dt›Mi”BPc:7DSBwx¼‰;6-F82J@4^F;ER>K<6^;-KB'IA(\O4qT:‹jA‹UJykIFQJF:DS>9B:VC4TX?4YE-C>=6"9D'QN,O\/BJ7P12l9*XD2U@9hP8F_A3@CG=.eP!EP/Z=:~N1pYD™THqOGhFAmX;]}FJ”bNj_SdCWZ=.j8.I2!?(##>%1P!†Vm°{aŸ„FojUECYd3s]<‡†B‡›WR‹^HpH6WB>C/:U(A[5Kj0Zl(Z„G`tRN{RPfJro:lƒRiwZyqJTm?Mb<•i0«½QOÕ Exs8uC7>7?C"9W*JT*_\6R`1YgCRg;IeACX9MO&GI+@p9[X=]vAi‘Bx‹=ušEs±UZ·jZ£dDi?\M@K4]Z,`†=M‡GBu?bb4R€Ncb?VaDTl=S}‹¯c‰ƒM¸Ÿt‘“}¹»vŸd¤aK³rU¤Œ]ž­l¯¹}y«si„RzlEkvP[[@T@/ŠjI›´|¥…eœ©‰èδ̪Œ­ã¶€Þªh¢x‡h‘d”§o¾¬qsq\ƒiKnu[\QEQZ3M]6_}\akKReF_l=Zx?[U.CS5sM:‹‰erž``Ÿe_žaS–TVn0o,sw=‘Š@l†HkV›Q¢‚K®tQ}nJœzR–›kjŸVFoBfl5‰ WSzCPb/EZ0=I+M_+\t<{|E”¥U™Ïwu V}–]wœMš{?ŠƒI¯£R†¨O…¦QŸpOŠ…^l¤o’vT˜­m£¨trŒ\YKn‘Uz¦]ŒŠQl£lfˆD>}87Y>l82‚•[º´|Âþµh̉NXŠ[e¶c‘¯Xê‹ûÿÌÖÿÕÐÿɯþ¬~ò¬lÔ…€Ñ€“ÚzºÙz½Çr¦·_¨±i‚µwµá”kDOP(@F)qiFŠ“Rj„Ikuai<^k-UX3^b?kc;dd@jZ;hS>tc?ogTkxJ\c?GS?@D271"74$6G*$7 "<44tkMY}Be[H\qOJ‡QM}KIl78=(IEP˜¸ÿ좥„SwO^ŒTj“` N•“Cn—MSx8;>'ES>oŒM€W‡œJZu4A[:LrPTZo³lŠÄfy¥OpUoŠTsJcp?itM~ŽSpSgŒCY=U|QŠg’­yޏ‰¤Ç€‹ Qv‡N|˜et¤sfªg_‰bq‘rr“PR`8IT-?='KI/Ur?S@Vv2Nh=_nMj€Tvƒ_‰žYz‘8>Y!0E3M#;`5BsJKyHXpEf…SlƒQr~G]l8Gd0c|@qFW|ELx_v°k•ÀfIB8QK;NE?PMFRO=DZB:O?.:;4'.?"!O0PO+sK2ve8RtMJ[ELJ7[C8HL>\E?Z[:B]E%C=.B5:A.1AB0YP.WR-hH8l]>F\IKCELD4ID5cB=–e6n»cJ—rUiJDX:SU/As?/O:+*!A*GW&M_:Xa=T_9rR;cV5X`KlR@`U<`V@qV6xdA›€Lf§dH€oP\LJ`CV\E|i=a”GAsO8X83J.=?-=Q3Ge?Gg=in6jsGKLI;B)PV![l8kT9a\4mpGbdCIn?f4¬£Haà—d’€B™Q4[abIn¢Q^–QZiF\sb~6cŠ/W‹6Y€5S{*T{*c~*e>[yHYa8^g3…Y6t£^Z¤]a€Mv \›³v‰¾{~e–ˆU‹¤dg…g›€Hjµzo_e¡eo“Yi”_e’Ymž[t©p{šhlƒZfLHg&…Bw³uw¥c`”iOnL\`5c~E\z=AR(Pd-Y‚;{‚Q¡­_x´sS…KYy?bc4~«S„jE•_0zpA”ŒXy™js[=wh?t¢`ƒ¡l…¯m—­ns}E~xG‰yQCRAk?/½šZÆ¥p…ˆyÙ±‰òÙ­Ý»žûÀ®ÿ§…ÆÚ°¾»ƒŸ¤vˆ“_¾sJ”œˆ~²¤ur[Y`9Na8`f?‚€NtƒZgc-RJ1NQ4ibBrgFd^@‰iU•[GQ/SK4~[8‚d;ir6hX7id?_tGgvJ}G’‘PiD^fAg`Ok{Jay:TmBa|L^gHmX>kR;aT>sjO{sf¬¾mz£`­vs¡SGP1:D4CG7ET4*:!.60TSR`~ILXDmdGut?^e4QG-JF:XUeš•’ï³mq†NbYr†]ƒ˜Qp–Fm Yv®`k’J@]8H_A\OpIl‡?^oEG€|hÆ–“Õz”¬e¢]p•Zh›ot¶awH^|2Cb-L[+X[4gs8V„HgYw‹Z¥–f¥®€§¸m€COp@b‹c˜º€§°jnŠlvš€¨ZW}ASz:AY1CI1Mi7[{E`~?JkESvIY~TmxHnv8Vg,O%EI0YA,EV5HH9LL4ER2OG;]^5WYDNG@ZL:8[3@[@FX9Sb;UlJZtUNqOWKGo?2aJ2OSBJ?=F>/DK6;G2lM0he/wYA€U?vcB~WJu]EikPudU—tQVŠ`ir[Hq;HPC[`8TrB6}P326D3"JX+Ea;PX:MU/[U1uB,‚P4wvKTfZMOKVX5XM6rN7bZ9{_IipD]yYZvWdqFOyH=vH2X8:H(GY*Od\4SK)R_4HgBg\7YQSƒRcm5hi5Z–N_ˆNMqAdrDt„NHŽ]@WG>M%EP'2I$E=$YR!>^)Ra']f0Y‹H\–F–>€¸\¢»g’ð…wÒ_°‚s‹\NžNO_+Y`)np.bJYŸSY–UN‘RTd>Qh/[y/d†7\Œ;S~5\~,W‚(W{+X|=9vKSZ2MFrKqŒOg£Un™cšY{™b[PMh1VU!MD!?B,‰i4_›qr‚Re‹SfyEez@f’Yv™Vy”gWvWZZ=_IZ‚NXsI`“cFc8dM9P5@T+kq?[œ_BG=bS0VoHYVd’Q²¢P{À|Œªl„·rGžaj}CU|EAQ%W_/SƒEmzAcV¶Àq{ÑŠ[…K_ŒFfv>n´V6cHLC&xX1k=•¹du Š€[Fq©lƒ­p}ºqd¤khoI{WŒ_\eQ’jP‘eƈaŠœˆË¿Ž±·–ÿlUÿ¡yÀ߯ª¯‘µžy“ p…¤t€zYʇn³eO¨vR_ˆYOmFunN‰Žgo¥qiuW|†UFb8TXDlWa~ffB-´…O¶Ï“µncŽGU‰CDt2?g(=d%Qp4v‚NS„Ub„OgI“c‚ow¡f—]¢•E‡™T„¤srU_5oY2¡tUˆ¶q‹Za˜enyOq†QYk@_[1‘œezS;b8nE&†|8r†Lƒ’N÷–\ËÔŒY|RXoBŒ›^q¢_xœZ†µs‹ÀzÃ|†³pw\qimœa`™E[l;s{>ª°Z¡âƒŽ¸v޵}‰¶ya¨N”ŽbÔú·Òá—àÿ°Õÿ³·ìˆÁî…ŸØy˜Ø}y•F~Jd}An{F°Ò‹§ºl¢±nn¥UgrR|Ô€kÄjS¡Ygh?uŠX´~‹±‡t¦vlžvX¢kgN©u‚Ê{l¤Q“°z¸×‚‰¬]zˆTiŠY­½›ÀÔ©ŸÙ›†¼q]sAb]8WyC`ŒHYEnˆO…žu¡¹”³}i¢nd™[y€S®o޽y|»r–¬rj‘Vi€rn²wW…PcjH`vLp|TrjSlsL|tSƒxHJV6HB3YI8p^WcE\zU„|T|uC}kRusQp~Q†KgzA^uBbX–´x~œ]o…VlpNeW:wWOWGQoOcbJhg\Z}ahtSWY7DY44F*PHI…‡¥¼»¥˜]ž›s‡¶‚€½ih—Hg”d›°|¨»m™NŠyGpQwˆHc|B^wKRrˆÀ¬Ão„‡@XtGs”YuŸb‚³l›¹`–Dhz8Kp.>_.:\,@a0Dh>h„N~Œ@qOŽ”j®atŒ@MxG\ZyœiŸ^q’k²ƒTgq@q}@Ll;?d;PqE`T`•V_”L_{FVTh~Fel3@a,9[-3X/=`=>hO^Žk­Ås˜¤Qh‚[p|by‰b}‘Vw…Odt>ftCxCDZGOZ4ZiAfxRx‚LkU[uWdpFU{FI|OJh@Zd2l‡;hcUNJsGFq0'mD0A4MJ!Hl9,`=FA*|Q"Z}3W9LI,nU/qt2l²Yj’Xj{Jsq;ca8JT4mP$V{0Qn@Qe5aZ)]‚8GoMMU0aZ8u{?L†UEkEFlB7W:1J'9B+7\);R#JV%k`)hp6dDm‘I“>°ÀS®Õ†£Ò}zèg©vG„PIe'Fc*L\(b`5|l=}¨TZ±gG•cCoD]h/]„3^@S‚Q>+f`2v·\JkHQI.NS-^N.Ñv:¶sz¨{}”pŽ»~‚¸tfŸd‡QÉža™x^ {g´•m•xf©‘t˜¨…ĵ}‚¡xwK;ä€nõŸ†¿®ˆ¥sxUwrNF3z˜g’eœ{_rƒXev\„d¹‹t…°•y¢wiz`Z[3ŽjJŽmR\c>DoMrS5uŠLVO6MG)bS.O|:Iy’{Mƒ¯`‡¯k\—UmX®‘cŽª}¢}”Ï ŠËˆn«\ƒºc‡‹CgqA—µv”»bi{q_BtqFljD[jY‡ŒlsŒV‚Dos>jhF‚V‡—_h|EcoD„}jÙ§uºY«^…rFcc=XT=h\9ŽfNÇ•vž«„°Í|–S•ˆQ¤šp€¦wv°u•UVa9e]Hwqh‘YT\9moCNlDYnz¼¿¹ë¼|yYˆf›¦jŒ¤Yi{fz¥—³Ù—š¥SfxUtB_ƒLrNv|@`nR|˜qŒ©TQh2IZ0Zn9WyDazFn†Rh…UzLbzI^…Wf‰:S]%>W#=Q+@_;WrG\ƒQrX´—W•Pd}Nncy‹_vUlˆB]v4H`28S-:V%5V/9dD5P9:@;3B3(765,)I/&]A0JWdY8UpGTY@KC6Q52N>*ON4Ga;HE9G@0OX7Gh=E\BLU?[_@_mDh{Vn|ZUZOdMA\P:GL@C:8H<6762.4'CC%QACM*JL2\Q5nQ5lVDvn>_FDhTQ^ICO2IJ)^H,mF&sY4mˆCl£gq·mY¯qI‹n=mIFR8ZZ-t{8z‚FssO„eSV_HHLAPX4epY*?\,OU&SM)Nk=>s6^a6Z…>QŒMN„O_yRbŠNXrVZ]2Qt8@qJ?d7Bi8=a18N'JE$In5Sb5Se(Xp2€0Œ¤IŒ¨cÈÊkê\­€AyLGd3Cc$K\,GW2]k9`uAxZ>p•LQ“`WJi€?cŽm–J9N0D(5H3R#IDlm1a^=zR5@.9I)Ig=Tt4qFsŽPw‹Z}‹Or‡Lm“F|Mƒ’VÀgr¯jkžfhždl¦b“b‰Ç€N‹hX\5cW-]U)l_2c^.N`/`_7^ŒQbxDq{?ea?P|K\p?d]1KwCOq2^i5Ž|7d“SEˆDLZ6q‡Owµ`]jMGM.FV3GY2{]0ƒ[>²|PžÉ~¢«‡¾t©zµ§|²„Ë™fÇrkz^Ì…i]¡‰Ã“deÛš†y^´xc§yT¼‚cmtSW7feF_V:zqA…Sp‡Ii€NW6mF-X9`y6n‰EhQ|k:[tCRhAIU-b_@ŒkC¢m9xIo¤[d•ChqFQi?]\2el?Xh:dqAlnMkcNShBjcBO_Co{_`i>p]7QŠcŽRš©a‘‡?RX-\gZt«…³¥j’ªc—›[’˜VXq>U_.BZ$Kf4_u:”R}PuŽVu‹[ƒ“{€±x_•]g˜aˆžgs‹CZV8nnH†‹Z’’`€˜€ŽÂ¡–ęбt¡¤eôñÿãv ˆB^^<]ZTjm`ikKojT}|\q‹f…}VoT‚‡ZTt@Kg8uvI©ŒW€E\n@v}[¼‚[tlI’pTpoGeTFnfLbiESR=žvh£¤j¹Ÿb”ŠTŠ™a§®n¿¬uߥe‰xGO^;T^Daxf† i^†T\ƒSi•{›·Èÿæ¸Ø­i‡—d™…O~R‰•{˜´–«Â»•YŠ}IgMYzUYrOb[n©z‘Ã‚Ž¹uy¨csŒcp|O‚vS„‘dzŽ\XnCa]8[b9H`>OwERr6Nd3>a9V€J`‚8I`-L^7Vt>]m{=Tt<[rNp…@Ab"6N#3M'>X/Xh3TN0SC1AR7TgD_R`Š\y”Zn‰DZo5Nl/C_26S,=J%6Q0QoDBD0DJ8GT<=K@+<6:2/M21hK4cg@qcQkYIgaH>YBG>8AI.P@4b@.U_@DaSPF=_I`X=d];XUAnT 6I.@Q6|Y?…K«kްuy¼yT›uNsOLb.]a-Xc+TY3mS3gb8JVBUO3ck7d†Fb‡ZkvLdy:ut6ar?]j=S€ELxPIxM{wH¶šI`¹V;lU(b‡C4ƒA5L!6G-N>A \[*i…QN›[f‰I`žTP–Wbq>bc9dU3brKPmFVh7mp7Zr>vS8ƒJyÆpt¯p}·oƒ²u˜¸uÎ~Tã?c?P1FV%Im5Rnh[4y\?ƒwRžÍ‡®Ì£ß’ŠÌ•Ü´{¶åšÇô¸‚pt{]zoR¾[@QWIÔ‚]°Ê™œÉ‰s‚a†gM‘aIdJ6zX=„uYw…^ƒ¿uk©i]c^TVYaqA·qF·À‰Œ¦€š{^mmO¬ZErU§ºwŽb^gKXw@Pj3]p4UqBU[_@_…;XQ\b4_fCGnKWYE‹qK]N-ad1PfAtfDeŠN{–FQuJ[U6gjK…Y¬µ¡ŒÈ©ŠikQo‰R–[†­io‡gK^Y}3Mx1xˆHU¸c5:#'(#*)7"@$7i72G’L+'4/PL[i,Xn2eo9ex2€^?mO˜ÁÅü¬Åú­xÚ}ÆÑ„ªìœ»ç޵Áq‹ŸTyŒCbr:dhSg>{€e…®vq¡h_}J|–WSy5Kc5[„MZ‚Ps€Z…š‹¨Ì¼¤Ý·¢Çƒ„RÛŒX¢„RxhJb`Mgi[‚lyjŠ›‚œozOy_:W_?sxJŠRg‡Qe„TjSk{I[pM‹Œm®‹ZvzZ€f…`st[†e…ƒ^j€]ƒ‚e³bŠV›€]¡h›œa¦—[‘’P‚…D][DUcV”ƒx‘¢„¡mpŽLˆj׳¼ÿÀžš]yJsrVrAQ~Ld‰Jkr@Ie,>[1Un0?G>H:+MO/DP=HJBKM9-L<@=;Y>6RM?VOBLH>;I?D==P=/EJ,]K/V@`yShdUZ@;IH:ZQAZ]?9ZKX:Vh7>h=6L9RM2d^'b`?bJ9VDf5>^2=\0^g/b˜GW“z_yIx…Nk–L˜©Wj¼uU‹WKT`“Zp©X¨Z~˜\i…Odq>_`1R^0Ca/A[,Wi+Pn-w}1[¤_GxKQj:Qt4Ha6Uo@?n;SQ,DvB;R>MH$Vv17j52P$0B2B5AYc'}›W…£ht“Sfjen7N˜Vl‚OKŒ[Kn6]ƒ6{z@_yXfˆQ\jGr†K[’QuŒI|•KluPs´Om“\MmGSK7UlA[r2yh?ªh—Õ‹Ÿ·{§Ð‹ºˆŽˆjÿ“m™‰‘v¥«šldYbJ?mK>Þ¥}¶Åš¦q„§lpc>Z\2Z`)y_1•~A­Äw¼Ìˆ™Æ‰˜ÏŒœÇ‰Æ_·‚p“l²Î˜‚sj–{VznMknVuv>„†BƒrDVcDNv>T\7McAk`8‹X]…Pcr5p…?hI„”amªw¦¦mmeBPg,hu4jQbhHdg?y–ISpCj[7Œ€W´šrÿĬ긖¡¡…•´Œ§¯x‡‹Z‹s‡VLe:Vj6@`,8T(;T9l}f˜«už£Tqm@}vc¥¨‡µ¶²’Tqe9^zHj~Z”Ÿxo›Z‹~O‚®\z²f¬\tDœ‰]˜¨d\\6VfO‘¬d°¯\Œ¹[|ŸSz´V‹¶X›ÎptÑnDŒNk3QA8WK;I[>:TC9EEC>?]E9wV7CnN-IL9/4P9)mR4b[CCaSCP?O0*OG/GZ>EN=AW6MQ>SC:tO8§xDˆZjƒdd~b[rLD[>IUAJ]pSG`7Nf+@{=Gj?Qg55b:4P;:N+MP2Žb6u‚TkaD‹s6‚¤Q|¡s“£_™œpN¿„;lf2U34A$3B$<< TW"P\$H_Cl;9]"6M%8G>Y&Kg3Ku3Lv7s0X `BpIPj3Ou6[q>RuD;U2bh78SB@K%Ec,Nl19_02A$.D"+CB=or3‚¢]bzQAU0.D)9>!FA&ZY-JQ0YL1p`4šŠ<ž¯n¨¥d©—d´Àp‡¿ˆ‹}ItwGpŽRq›\w’WlˆR›tNŠ«V\Ã{j}Vt˜Tl­nWœ_h†Nq¢[‹°kdÈm[“VUwB£n:uR]Xc{HkŠOeŠKi~KlŸLp—Yyµ[išOy©Wh¬hDrMhn3ž•aàÙ–ˆt‹šW“¦kŽ‘^rŠ\mmT’sPÒŽcË—sn‚mcdOÝ‘kÚ­‹ Í•йzz]PU=TM%SH/QE,ƒo?žªkœnRŒpO¦qWŒgT\O„RKhQ¾£iƒ‘je“`œfG`‹VW‰Ia}DlwHKX6Hs>^nEJq5JU&W[,RR0NJ%\t4y—Z©¿wÌÜ£‚†I^l6V_.bg1pˆCauL_tXv}H_‹G|c;Ÿ©n¶µvéÀ§¢vı†ê­zŒ—Xsm?‰rGZT9·{WQn9Wr9S}@a}:qŽFƒƒ@—šZp‡RdW@NG25*+&,1.“™j4p7/)?G,­yï”D£I:X4GcGlxGqq1¢~I¥Ñq£å‹ÓÿŸÂð–¿vFi:382E-Fc:Pk=Mi3Uo+f‰BH€BOa9@\7H_?Rn6b{\nuMK‡PTi8mg(r‚9qŽ]{£^‰Ÿqe¡g>Œq8T=5S)4C,;AIDHS^59O+FV.N]=V]€KZ\4bW=ge7ŒJ…nSzcJhcFˆR?y]DH?mKCvfN„tLs`Hlw\{wNi³axžb]¥dmvT[3-V00<$CB&SS)”„N=f4,M'dkH×ÿ”xáxešS‚Àzs̆X¥JMc8¥®pÌõ“ÄÞ}s™Ou€T,I-6P2Vm?Ge4=Q.IS1Xj>Le<[k@j}H{‰N[vVV‹`uˆf€ƒb‘wEtN%]V+FV;~MVd@uqZ•dtNŸ¸l…¤WW…MSŠjvªup e‘³z›¡hcv@b\4BH"A="aP3Zu9L^Ex’s„¢rnan…[eoInƒ:{~@_q@d†Wf¦e]›OW}9`vD‡Ÿx®ë™¸ä¢×„¤ÜŽŒÏzf™^ym†zj‰yeˆqTŠwdm†s}³sžo€|ihoU`cFrdCqgKxgCthKymO{}PjnRg|Lc~JlyK~rX‡„]_jCrgG\bALe8Ma8PsG`ƒPm‡V}[}„V‡‡X¡†W‰‰U†|^lrVhmY•}f“bo‚d}šmˆ¨d‚•T…~Kj…U£¢]ˆŠY„ŒSŠ–Pz~HaiLi‚f‚ªnƒ­cq–T[‹Lg}P‰…^„–U‚ybÇ¥¢ÈÊ·¤Ù¦¤Á¤µ‚¤Çz™Î‡¥Þp„±LeDjS™d~œLgˆCNyDFzK[{Jsi4^V%?U+C[DVoDPo::X-2D!<@)I@9TWAOmK^xBL^,3=(5F0CYAGe;Qb=aqG]o:Yd*?R/?R:Na>gr;WT/>M5He6Je7>W70J4/N;BcK[€XŠ‘Z}”W_ˆ`n›}—ÉŽÆ]c•FWy7;L/DS-HP/2Q58=35B.DI1SJ8Xg>ViMEdUY[SzWN^[MfTGTHDJ<=B?69:535-U;)XT0CEA=;6BI0_L5HXA=Y7?O+uO(•v;–_RvmYn`clc[DrQ7_ALK62K2KB*EV(:O5hL3MR3=@8FC1[H(f0Y[Ejo.>46(!FAP^+)a<416R:AZ*2O<7B1H*H":^%VM4`q;LrD9qOE];5b1;U1QS(Yr+Xy@d†EmCnw?c_:r_4ix@6vLDI;bP&Sw7QPIMjr9S”CFk>A]1EW6Xo<•…IT–nm€]F’S8[@JM,fc8wˆNQm¬{x‚a<žW@[J3B$&>('/3+6B;P!FF#H\-bY7PŽPG~`DY4;[6l]/{w9n‹Pt›Ty£Mƒ¤j’Æ~xß™_ËC¤bAlATP$i\*bt6>q8KW-Mg1Tr?d”Jn²`m¼m£³i~Ät¸lz \c‰RJr8Aj/Pc/Je7?iH!G^+:d/2O%>C(HX-7W1d_*j“OJvEHM(@E(UK'MS3iU5L`=eoCTb6Vf1^`:_zJ]uEX‹G}‡WL‘T<_@=K,JN)^V1RHZx8Mb9Ml0zV*µ˜M’ë„ëp®jzžW™²izÀ|alE‹x9cœgvƒ[|ŠRf›^[wIPf3b^1p’Mt«^u±_i¢]„ŸQ‡Äg½Ãyi|lœrA¸…[ËŸlŠ«t ‚R¢lC˜uNzb;¯›a±Ò“µ«tÂÓ˜ú¯‹ÿ³ˆcš|] r•”^|ƒMu˜ZkuFolKuM~‡IG;iM`gRjxaanTdbO`WLqrTWjDqT0j}XX[@“‡Jw‹hbƒDJy]6:H4TxPE‰ZF|Oj†X ‘U³¨iŸÃmlR‡šH–Zw•Yqºi©­\“Vs_4OR0gwHBk?Qo>G_+8W0;c9Jc?XkBVso‹Vq‚KfNt‰Yk~=ah9Œ…GdsL_P:u[7[Z/FB C@,|lZ®Ã‹žËˆŽÈ~®Ò‰˜Îv†µl­Ç…¡´k™Ÿb‚‚_˜|n›²‚¦ÈŽ²ãŸ Þ–—Ê{t‘V]|FVxE`bdgRglQ_|P^lCjlF{hD€e;m__]5Wd8gtG~sJ{„Ml|Om|Mf{NbtGfuQ”›p¡w¢”oµ™r’gy—a{Z†ŽT…Uy‹PtŠ[žlžž_‹ˆJhnAtSDyeKw\x—fy“^x‘Zn›Zg†Rr‘_…JY]:‰{iÿŸ‘ÿÀš¤¹š¶rÇ Û“³äw»ZgžM\ŠN|^}“[k•TbOfzDjn5Ye,E]3Q`9J\>S_>Uq@bf>WT1KU4IM;JLBaqPg‰LTp:@U2DL,G>/RG,NQ4Td?fx>Ma8BY3SY?_g?]iB*AP2M\3Bm=ImHelF]‚Lb…\Yw\NgUZOEeR=UTEKDE`@>8P<:8;P;/ZF6CB7<6;?B0AO0;P9ExE0UFTB8UV*NX;W\97Z;E8.9K,UD1~c9I„V)R_"'-/"G:J],3M57I/HD(DO1,M007++=!G37V$l]:|r=V‚QDyLKpUGoA=sJMbFŒBAe8FX-\S6ƒCz blŸhf[=ŒK=[IPY0au=euN}hA_²jp‚jRŒO2vR'2++3/?"3H$?=%=X)HT(RO)ec5fBK‘_VuDK‚Ke{Nu‰Ky™Px«^€°[¦¸|·È‹©ñ—}ÒZ«i9pF5]0>a,Ae4R{;XHb¤Zx¢Y‹­bˆ«i¤_u†Ln…XWzDL^:@`2H_2Jn(Te/Kw5BLAkA?M*GN&=^,9T0:E!W\.Uz@Kv=B\,W`'‡3Pœ[BiF(?I)LEVB$^`8K‰TVk?p~IˆnS†cGdxAb‚Go‘\ZPFkKGX2AY-RX-NuOWk@V]1R_/_g,•¬P¼Ìs£á†zÛ…‚¶oŸÁ{PiUo8ya4jd6csBxˆTb‹OA`=QS,VN1zl:…©a‹Çqq½nŠ‹Hž®M´Øyo¦lq=§rJ©z]ˆ‰Oi°fŸ…Zy‡]iiC£“j㽆±½“šn¸ç°‚šn…gF‘U‹‰[zqPumF~yBja2ŠP6…ƒFpyT^hF’nM¡tP‹uYzr\™{_sl[qƒYJmPUS8lgNXlQžm7_zGR]1\r4T_1gs84a;BC%UZ/[šOLQY]M½Œilw;Ko,Ok.L]3Ll+Pm.a^3tiFg˜P™³}€Ô©d—ul“i]žkŒPŠŽInq3r\1n\7qfI€kN—pJjvPf|K—xQš¨zz‡Wr}@mEP>]†Md‚S[]CfiGdmNk`aŠlXaœ¨pŒËxu´iz¯hu¦jÄÄ|l¡Zu¤T|¡[‹¾v§Îtk‚Esš[7X,RM1iyI[ŸVNS;b=Hc;Qi^`Md|]nŒU_oPasQuxLjt>bW8Y[EctWhtUTsFes>Zj9\i;Ro=VzKc‚C^zJc‹f¡pµ¢iŠ‹j›hŽ©nЬhn’<[j-oi7y}Jtœbƒ§o¢¨e…QwwKjzJ_‡[ežvg’cfŒPy›a{¢^wSx Ts‡@YT:ir\~–Òž©¢ƒŠ¹Œ—щœÓ“¾×—Ìm»ec¨hc™nm¡sx¨pv‘MbuP]:UV5]`AY{J\yGsyF^v>K[=I]9Oa9PXDdkJYuFW|JdŒUh‰Ob•c¡]qƒGTZ1E^*>]-^T/CW.Va6ak@bLR„\pw\pƒV`‰_V…\HgSRB?\J4SX7XUHLRAIN@IN9CF7L88CH3AK;VL:AK:8H69A03C/BJ+VUC^)dA,X8.S27W/+`?,xU9\vDDvWK`ENI1G?5EA/G=0MG)AM3^S;myIA‹sc8=Q8=@24E#/D'0C$G9^Y$]tD_„^W{K^rKT~HMcNGV:MR0C`7:g=<_75]25]*]V$Tc0JX;?g2J\9Qd9Wg8MqGToDby?@€FCX7FY3cZ<|x;tUY€RZ`DLy?JtQOa>`q:fŒOŠ…Gt»[c«^†U.„I&E8:7;N0Cb6=kIY'.f))@'NAbp3g¬RXZ@u?4N'[<%lc0Ÿ†Vc†\ftMPx?KH-JU(hd3SvSHo=VU/Nl4mq-xBzB¥}G”¶ZžÔydÄ{\iD\u6Nz@B\y{RlTv˜b}¦Z¥’K…N~‰RpŠX`‹enš`k†M^~Lu‹Q•_z¡iªh¡YN{DdmXskŽž{µœz«ª„§¶‘¤×‰­µo–ªh·ƒ‡Ä‰¿ŠŽ½„©¼pœ›Hbg-F[);M)?N3PcLewEWi=ZeT\KLlEH_@PL7MJ8daHd€EXn=U_?Vb=J[>LU/QJ3UcCQ4A9,7G:9J4BK&=X#2H*6/(/&%E\0sA+i70YR9EbPU4@VA6D42<*9D+0B//D+HG+|W*^k:UnFFaDJ[;CW16Y99T1?K&A[,Uh8PbGZYBcp=F_buKr…Da€JyS6މ:]¥uUuVJj42qAKF0:^92>4KG"Sy>CrN@b5]_.xo+\MiP˜H}§i¤gt]…‰S“¡R•¥w}žss¡fu‘`l‘TjŽYl“RY„PMl<Mw=Jh=\T0h`+ab8ieHN%6d-)C*A?'ySu™CU\?jA6G(7?!>G$W\5Ud>\~Ko€OZzRVT7VY+7I0:.$PH#k^?^g=`ˆVKLAK7Dc9bR5RY8FR,DW-K]*fh/Us1Dk._^*ЇF¯ÂfuçvZÄ{]‰W_y?_~;e‹NZoFR{O>hNMA-yc?iyNuxE|©Zm´Yš²Yr¥ikSYoG„ƒGÀ{P”‘Zˆ—^–¼g•‹XxzW˜~QvŒX¢^J²°w{phš…dŸžj™ši´˜b„ƒQtfN{pNdR~…Ly›\ˆZ„›b‘X¬dugº‚p©™…z†o|sVTyVXeKWjIx}Yj`K`<\`(Hx:Gr/Hh-Oe9Jg9Zy:ŒŸQÇÌ{u«jz;—qX{€cg b†«nŠÈQšXSu1gx@eeC†iOg©fY_=kQ-ºoDä]mžcp}Ob£qz¤t†–`ƒ{I‰{DwrH©…\Çø¨åÿ´uyCkzM^yCCS3QN9vAœšf¸p_‰lyp]~i]nZNceAoƒ>x­`gFzŽOƒŒCipAMmFRh<¶¹€Úÿ˜~´]dgMTkD`u9G_6U_A”ł◼QYšD0Z/3a:+O.7R4hƒRIv@t‡T~­o}ª`†§`œÅs¸Ý}‹ÚpfsFpuLyŽ^†Yb‹G_z8iBWsVrCK\5IU,GU0M[†ª\G“†MC\Z@5VU8ThBO[@IJ3`‰Xe‹aBvc?M?UM-Mm6bdHlkDg†OT{KDY80N)Q=tVI[@XKVZ.Fy.Xr<4sC;E=fm9A•YRlOTŠUMxSi_+\y/bxF{~BqƒHe…KRuCgc=z~C{GVgBHp9OO/-Q$6A$ZW#^ˆE]XW†R5hA8P+>O)LO)TT)TATE ZU&Lc;6o4;Z0JV(}p/P‘SEh>Ae(I_)HZ&0`-'D!':065E#JN Al)AE-FS0aH1_c7NsGcY;HyFLlH>xNAc?Bm?Pk>Nx?Ys8Rˆ:\zA„¬\”ŠV©Îd—É‚yÐrO¶s\cAn}=yNmˆY\ lXŽ`}‘Zd—dh‹TpŽSe;…r9’–R€¯m_¯ZŒM‰‰P€†L}{A ¥]”–gšˆ^ŽNjgL¢cJ´Œa¬™h‘šc—˜Z£}[¥yS¯”Uj|i{gHdtI‚~O‡§kŒ›o“˜w…¢~ w–}æ©€¹°•‚Ÿ‰~”z}‡q‘uOt[zQ3DW7R[;FY6Oi-Wt1Sˆ?^ŠDk¢RhŸMŠ¡Wš®\R…Bai.„L“ºwqŽLŸ”Q‹€˜ˆjl͉ML=GJ4Na@oi9bwMr^”¤YµÂ„Ûl˜Z}wA†‚P¬«yÿÿÁ¿ÿ¥Iy?VQ+T\7PZ3\y>g}>¬ŠC‚HªU‡…gwl[l[Vg]GsH”¨\m¢ip—VUpI`pR”Œes²n€L§¯wi€J[kUjNq\—mrˆXs…I~uZ`†Q\q<{`2fk3xCkˆHwR„Œ\Œ’aŠŸkk£T_—WÁwˆÒt‰Èt†Âg{ŸWqSwWxœbƒ«k±Y`„Cc€Fa†U—¨_–°Gkƒ=`}X‡ »Î‰£¯ey„HfjChc7Oi3Aa9UfPt‹[n{BN_8[W:MbA\jQh€j^‘jPƒYnˆPeˆGWnCm[JreGrlGUxQO…FUŽFSˆHWf5BM7NN:f]EwyT“„Q_e9CX8Wf?Oe-;G)7M8LpER‹Mk˜Ji{>\d?BZ7AL01C3>\F[sS`j=Q_9KG7KS8IN8YZ5Dd?N^Bs[D_z@JwMQgNNc>L[F[[IfdHZeXTYSGVICH?7>B.?E"KO#KW%/G6[>-8k18:7>,(A1'=<.QC.Q\,W`8LO2YF4wK8¨`AlŒYMqiYKFWV>UgGGIF8O8@M*FB+H<*VL2@a L@ 6e*)U5KM'cY)Ro:Ic;LP,NP(Qd8JrGMQ:>Q0;X;GD$aZ&gqC[sS=bFC(lUH™F:`VDR#\X(`7NIi€Nq•Un§g…¦mm©|C—r_bCcƒ0]ŽJ]RKb3Hf4OFSŠUW‡KMwJOiF`x@@tOJK1TX,_j9H|FHa;Je3Gb5Bdl`<„‚UÉÍ–ÿÿ¹Ý|Ct8>Z>SjFbi;_Oj¡aazCro0x†;’ŠRŒeSyxQƒ€Vƒ§YuyKwnHdtHevL~«{·ë“’±doƒ^¹Æ’>a0A; E!c;5Sd?pU¤•sˆ™dm–E——j¯’lŽ^=gT»™„Ö‹t«u‰Ÿu¥¨q«p°d·Ï‡®Ü„‰™Iu…Ee‚Q‚xYĈ__›lk‹geuJAU1RZFbh`Ž™}”œgddFgdQuggzbk]LXK;KF3±XNk~J4;(5B-9U2V`Af~PhtIn~Dg|K€{V†t[Í´”vÀkR…>Yn>eg>cuGr’h‰ÅŠÃèªÁÿ¸Ìü¿°ÿ¨‡Î”€Ï“kÈ•ƒÇž”ˆ‘¯r„“W…‡OkˆU`jO{^MocJjcW”yZŽvKe^HqzU\xKST=YK6[O:ZZJgiUu}MXhK«{d§“Xvy>fj<ƒnTpŽSY{DJr<[rFrvCgfArzS}…M}Nm‡Cn”]ŠÐ}—Êi©TvGh‚PWr8EM*YVAtvWƒI`gDaxIf€>t‰>dy1Ih@VƒJt|Y·’x¡ª„€²yn£in–Yd…DIq>]lRnˆ^Y€SMsDIj:I^AV`Knlkr‘{smi”Zb‹MUwIYkMdwSb„cy§ss³df—Kd•Q[{;ML3@X.>P7Z[B~m>a\9DQ/N];Yq77P+4U?[ŠLb‹Kfu;UX)*;E'LL06V1:N3VG.bW0\r=KzJRoMZsKQmQH[OEJI2K=:A8>B>DC2@E.5L5-I42:+71#>7#R@'CI'3A1=>)aK$BR%Z8)S[+'L:.1-<0SG)ŠcJXaN\LJgR9pjMOtUKIHIG8?c=AWAQN:RT8\`CfrJVqLBhG=^?Me;6n<'M:+?!+=$:-6+8I4NZ)Bt8Pi;>\:29+8:JB!MP&IZ/4Q5P/)BM'/WG9C'PL G^>7`I?L=PE2T_-Rh?VIerFN:7eYK)JY$@_/7[.8R,6W)Y*NT,KY7hp-H•O@[GA`/3\01@!9G!AP!4C&-?'4@@?Ck'BM-OZ6TeBQDTu7Ug,TI\m—l=wJ†yJ€ŽVXˆe[N9Sr?OgiU*€Lr¾ŠPvaYnI“X[IVkD~hB[oFMq<`v7lo8R†´j Èp‡ÄovZ€]:¥‰\q³yyV~P•¢d¸q=ª~P˜„aà›pú¡~Á—w¶¡xÙ”`ÿxf¸w]Üm]Ò{d±•z‹¡k•—e¾•vy£s[~__Ht‚V;T?P@.JX:__AZ…XAyKWd>K‡D3U4GJ3`v?PEuU4RP,Nd,~p6lœU[ObT-LP.`n5Vn1nf,·lJWkHÇqnâ¥OTG_+~”g¨²ƒƒ„Uv—Y‡šVOkFX`=lkEŠYæ£xìÖqƒ^I[-xrMyÓ–m§uy˜_—°qb²bU‚Dc@ut6–r9 †<™z4’O[~GiZ2up@x¢XĵjŪdlŽS´¨ƒ°Á…E`2+;$/,#WH:ylZ–e½±ƒ©¸~j—M¦«eèT{i‚tÚî¥ÄÊ‚²’r¸¥‚¥ª{‘Ž\s^¶Ö¤ì‰jHpƒU‚˜c†„^™•Xž‘d”}Q_`6VO>B<&@0 N3$bJ3y]Dµ…Dp€:DI'[N-o\:vjFwmS‡boz[‚oU™sQ¢‘`¬¨e‹Xzy]’\Ã}pŽgiXJ]_Phx`¸ŠgBnNdtQpŽV|™VŒPspAfiDqŠ`uWrpW¢œŒ¤Ñ‡]†E[`7iT5d\8tpQ±ÂƒÀî­ãÿÒÚÿãÜÿå¿ÿËÄò¨¯Õ† ¯iЉVxŠ_pclŒf|–lksXŠlfŽ„bŠ\¤VŽtJsvQr|ZgvLidJ]ZOWO9cU@‚jL`9lS5kYE‹vMt`9sl@d^=ljSu†Wa‡P|}Nˆ|O„H‹‚M‘vFƒ‡=^~1[uM…ZtŸXZ€QRyR^‡X\S8j::K+?:+dM:W`;[l1Wj2X|C]†KL|Y`rUh~VZ{_®ž†ÀÀ…”©y‡—ZxˆKPr=ZrRu‰^q’\jE[b3RM7_fMƒq`†‘qk…ckzWeT^€MgqLZhUh‡v”ÀŒ’¿cuœTj‘Ie~;ET6SM6GL3AX1B]6IX0@I2?N5Xg;Hn?NsF^wFan;Va+8C/>"8I5maNt€Ol‡ThczŽo„“X>>*7>(9F,AF-4M)%F$?9!cT"mf9hm?i†J]ŽcMpWBK@HJ3NV8GZD;QDN>;AD-Q;$?B)7K/GC0XJ1^_;4`BJA6K[-]SCxX?ƒb6hjEafUT[H[W=q`EuoNOpYL[O[M=zQ8[Hz_FnZF[`ISiHIY=N\9Nf?Lz:8]>1?09Q(6M-7?&]?"UL*4eL8D*QHJd<^nAGyP=SL?<(XE!Tv2RoHel46€SCB44b,2O5XJ'_z&;ZMS=Lf$^jGh|?sJ€žY«¤d©½rs¹šv›vhdSXlb5EŸO6dMAP+s="e†=bbMQEm?3R19L/AU0A^6@S/,M+:D!DZ%=a+?Y+:W59[.4Z.;W)FX'F])Hc/;_>5P.SQ'V}9duC[RGyP@g8?R,:G*0D$/68#O,GH*:V=fF$b‹E`y>p~F‹˜TTfR[H0_^2Vg3Vd0nxI^O\o7}EC{YOZ2“H*•“LMŽ[Op2vi3x7{¼`I©dVj;…]7•žVd¼€’fr‘Tg€FVj9x^2Xj6Pu2ZKg‰Pk~@q^8«r?§Ó{jуeŽ^¬ŒT”“`‚uD•šQ£´x{· Ÿ€p‰s\ÍtO¨V;¿hL‘‡Q–¥{ ynŒaL[M¨kY¥uU‚xAº›cÄšx‡¸ƒ°{„pn‹hPuYC\@_H,dG*|X7Wg5bs=T—YN\8Se@dxB]x>Qn=8b5Ya1[s4l|2Im5IZ7JjERo=Ea*Qd+ƒa,SR*›N=ÊPmEX[3º›fesFRN-RS,ZJ,]L/€\7q‚Grr;•Œb°ÃŽqº=tBw€DÅÌ”÷¥‘Ù†‰²pƒ¬s}¤hxœNV€6jq4Wx+c4„MzLe’Hoƒ3ŽF„œUvU~}TІZoD>M.82.HODXuo™»°¯Ù¢æè§Ïð¤d£O™°kÖõ­ÆéšÀÈ•Áè¢ÐŠ–k¶­‹ À‹ƒše‘‹hÈÖ›µí‚„š\ˆqÊœp»¥kž†`ŒmJf‚FN\C_gF64&88*@M6VQCZ{U]¨UM‚EObBZwPQ€So€[˜”„Á¬–áw¢Zˆa‚™j—žb¢›V‹X­šc‘ŠdÄ“s—­†šÆ©•È¡œÆŽ±€ƒ´“°wœ¤]ˆˆXnnTg`I‚|R~pNvf¤»’«è„`†JRO4NA*HC(EH7†…v¿ðÂåÿòÿÿáñú¶Èà ¹m~–bx™bV‚Ji’f|žj‹‘c‹¡k{“i†ž~”¹xŠFdP1iF7v\CuxUly\|zd‚‡cnmHlX=tOZn8[L0JV@yqZz›ae–^nƒLqpKt‡k{«bk°j’¸cÀ[w­IkƒGdƒDZv1Nh1_~L{³n~Æum´dSzIs}`hdRŒPV`8bP;LN:O[Om@ElHdAlpL‡|V|Œ^ˆ—gH@,EB*1@+0?*/?' 9=53DV:'q[-oŠDJŽ`@ePHF6QH/YP8IOA;KAB=164+;6)D;#@H01M1;5.19"/2!24!14D;I@ IMpKD^ATO6Vf9JJBb?=J*OM*IJ%;J$8I$;_*Lo9Gh>IU6_S-O„OL…J8uH7WBEJ.0IMHY;\P4J‡F5kU0@3KFPb+Lo:oj<=™^IQK7k23F4JH+ma,QœPJ^Me^)X‰Gf†d™X†¶w§ºvš¶t|œpY{V^]6@jPlT+K„,@fF2^,U6/p^*Z›]J‰L9]0D^,DX97H);F#:K$7C%;U/@a+9I%:> ;I&AY.8[18V-8X%C[&LX#9d3:T8XV+Sr4gyBTŒOGlN@j70[0+<%':)79@>; SX$Kx8:eBP\0Uo4Ks2Ag6A\1CE"8V-;C$;L&;E3J%3<NG&Rn7Kk7R]4^r8V‹MS‹M\ˆNp—`x­o{¼}gº†P¤}NœoS‡kp}_HYON=,9I)33"G5>R,g\5X—Q]c4~Ip’ZD}RIK7KQ$E`-xg8mŠRZ}?_g7m~=Qs:M]4W[1Šl;LMj/I`,Uj8J[?nbZ‹Ã†PmCea&uh76R59A#HV2UfŒ‚jŒ™w˜›{­Æt ¨c¿¨ª¯u³yžº}ï©€ÿ˜uófÈ•k¦—|‰›i˜[“{QšQ¢Š]¦m–Ÿa´¢‚­É Ï–¤Ò— Çމ¨xˆ¨hˆ£hÁ¹l¨Ð€sŠbŠX†¦cªÈ„»å‰´äwÊyL}=9E6;E:6<3).):+=7"L7+E>/'966&$* -& (85AB fJ%OL5a_3aq:sjD`zQXuWolEivFOyN:uTMUF|U-_[3[T@ˆY?^ZC^VIˆWB‚nOkqc\`]WZMcbASwENpL[lEbpEZ_F:l@8R8:I1/D(6<(1: M>(h[(QF4RIRCtR&a‡Ob†ST‰TSŠSDiG>K=6H*@B"QH'`d:/c=>:/H[3]BV9+^s24†W7MM?O&QT.^j9|ƒKR›TOj]:lB7KU4=X#+];-9(1:3M%JN)Fc,8h5*B)3tUA?2FJ3MZ8ssJT¤ZWM3ƒy9V…QkO4MlCEq6PV,‚W4R~DXa3^h4frBH^E`V,ee:_yEY2_ƒ7Gk4@J!VT!qm9uŒIX¯`fm>¡}H޽xvÃx•Y_ŠD`Š>mˆOmzEw“Rp¢Q„˜Z‹©jœ¨mÀj“¥nSfpgEroIo’DgwPhW<}_B›lMÏ`GÔtZ¶¤}·ÙžÙ°¨¥ŒÃ€[š†YŒ€a~|b[k?ºy]¦Î¡¾°xqŒ[]mKUY>b^GjU@lZLYvJV}PacKpkLrb:s{FS|KLP5HN2WI7``?`W5{o9_™J:i+8GFW%d`6^Z7Qf8Zl2esBd™r~›r“¡wP‡MCl3Kn?@`DImBh„GeJ__8dgL®r¥²[¸Éi¸Ëkm›RlRn§Q|žHx˜H¹rgŸY}Z:\—XBW-PY-Oa2pp1|…A¦•RšœL~†7S\+c\5‚ˆPš—[»«}¢›Y6C ^71phQo}c\ƒiWŒuX‹fƒ¡b†“]j|GŸŽY¹½p°»r¼Ò‰Å÷›Éöœ¼àƒÍºtÎÃs›wU®Â~–Í€¼o¤¸r¹Ï’Ìu¯p®Ù€w¸si¨b]gBW]5Z`7a]2¥d6Ê~B›|M†pK€sQʲi´…U°„Q³–cÒ‘xÇŒvž|moh™wr›’n‘–aˆ|Y‰|d»Œlµ‰s«šx‹‡bªqX¤‰b¨œpªµt£aƒ—b|”[³•]ÿÁv«\›…U•¼t¥½u••Vµµ‹­å’pº…R·˜vرŸï ¶Äqª€K’{\±Å“Èí±¥ÎubzOZw]¯yŒÂl•´h’¶d•¾d„¶Wt•V~¢\p…UfXV€\bƒVe‰bt‘t}¤‹®•–» ‘¿Ž†©xt•h‡‹]fxJ€ˆbs¥[p˜]}›SlšDX„8`n4†yAŒŠP¥¤f™²Xwš@a:X+Jg=V+R^Bx…QwŒE_€Tqƒ|´‚n¦|Œªtv‹EWL+>8(?ILt†~y®rr¢f} €y±™ĉƒžuy•aX†nm ƒŒÇ{e­`c…N\Š_x•sˆ•v†Œ`VyLUkG_g?a_\”š´v…„V\qNKmJ=c@Kf_†¶–›Ýˆ‡¸`b™UdgY^Rahš}y´tn«SOy@[mOtkz©uh¡sh¡md—l]jX—s`¨hf¥k[—w½ƒÃjxœM^tKUeDRe@Q]3@7+G>(=>+/;/#8).2'33 A5XR)_e:moBYvMTqENpEJh@DS>1D1)7,83&G7"OB(9E0@C3"C0.'%)#0% @&X@'TK*:6&=;,KJ-LL+kR/bv>GiFeV:~u8ixI5gU>CAbM&US)aW7W]=wSHk[D‚fP’xXuj^_aNXcI`rAZhBewJ^…VQ~QRnFKK=:Q:7E7+G+(4$13C9ZD%eV/G@F|N~ZBaqHifEw‹IiSDŠWCjE9S7L5EW+\W0wp9e’IX˜dC~N;YCFO.cl=`™On h¥cŒ±vr–{Yv]Lf=VU(`g$C€BVIE†W94€o>@5HL@w8IY3`j;cHarXGˆI8e:@P)1k1(N?9;&NV*Kh?@h4;W2)G&.97@3B)(6",47;>J J["Hr6=l;K^,Md)Zd3[†E?lMF<*6P'/X'.E& /&#96L['^wBW~F9o@>N$S^"L~?;c:BL(O^;;T8=R)1F$9I CQ(KN*\j6Ja9Vj/a=`zct5eb6fX/†o8m’IœY‘ž}‰¥q}–RJj›ex{ImŸ\†—Tr’euiIpY=mN5wQ6’sH }Hÿ‰Tÿ¡]Çÿã·ÿÿ¢þÑ¢Œi„zOy€]·‚oÿ’r±Šešd]a…^ux?wr7™Cjj7œhC_u]X|W_[Cd\1MNA[ACF0\<-S`JJA1SL4\y<<`,/R!INiT*i‚Gj»ge°cq£]Œ¥k‡¼‹ˆÅ‚Å…hí™lí mÇ•tÈ{e¡VpVl²zÂz‚Âgr‡Au‹9w†=fŠC‰Í}à„a‡Dko6•yGj¤Vab;w‚AIp:meE@j;ZG*ry5‹‘MqŒ>Wi7DH5RME[tG^C0£jVWU13N6]]Q‰ˆsµ‡o¡„}£…z§u‹¸mÁtc‰Np™L˜ŽQ¤¥d­ÎnÉÔr»Äl¦Äfºc•Âax·_¥¿xÁy¿nµi¸½u·ÅŽšÔ—£ì¡ˆÛ““ÑvŒ`ieMiQ8YNE`hOk’SbwIboM†…V³©e“W•€h¬•s¾›z㞀̨~Ф†¯¢¸ i’š\¤”_š^½˜_Ú˜dÑc¤rQwlHnkBd\=r\5qc>ojJlwXm‹l‘—j¦˜Y}h™¶t~˜KRjPŠ©”»ÿɳÿÔÁÿÃÃÙˆ›ZprDOnGMmUŽ«‘»ñ¡~­^UO=f}U‘©c’¾fz«[ˆ©WŠšMtz@kŽYŒµdy“gЏ…~¼€x¬wožv}©„Ž»™˜Æ©¨Ìœ¦µ‡š°l„™S€vGon]Y–ƒ´Ü†“¾ff¢fp¦{¹}xµ€q­‚€ªvz£be–MR{L_Y{‡a|Šg‚—t€žst¢y†³}‘³s„¤cošmŠ®}Œ¶ge‘HJf;K[Ele@K`6>:*E<)5?.+6(7=+1F+97)@<%JN(MZ0E_8O^8J]7Ia>=]>9'\V*7c4>D7WL&Tc'=d11K12F2PO0^W4UZ7eZ@ibPƒ_QˆpWok_\fU`pTZPciNqt@d~I`sX_~QVkLLR@>J91H7'A,'6".5>4<1 H1!`S#[t>s†LCxQ\]HouC^„JdpEQxD7xD,P7;A$Ea/1S5<;'ZG=`3E]=NP5VS1@f>AK7CZ+GS.cb-}‡?n°`O˜d@…c_Rn˜W}¢^|°o{‘keS`pRKnA>[;?b,VS&Sr-gtO—eJ.…n*98GC&In9Qd:[i@[v@OoHKi;1`9@P,E^,8qL]dPH^HKg<:k:4R/,K+,98?!.D$'*423C&1D%L=#Pa)K~QH>[_;tX7§m6¸’T´ÊŒì²c¯ d\P{MW€KFf?KV-Si+Z};C…M/M+E4![W0\Z<€}Ef©_eˆRc…I}>l¦jT›sRY6VX,Ye/u‰9d~C„v=”QxœYmŒLo|Eb„R|ƒR_˜K‡i=ƒ_B^eD`N?QNCoXHV†~K˜‚SÁ‘Tý‡Tÿ¤_ÿ阎¹ˆ”¶¢Žƒ³–l¢‹mß½ ~Ϧ­‡Tuu=jc@ns=cj7]q6wa1zL$€b?WeH[^1cƒ@DfEJO?[S9qsXmN?NT=Ju<@\2:g.Fj+^p.‹€@™§]q?Œ‰\Ždª‚\‰»x³œ^ÌË‹Ýÿ¼¾ÿÇŸì¤nÂn|‘Gš‘GŒ£Mm—?W‘?O~5Wf%k^%µ¯fËuMˆ6cj0i=‡˜CRq?qr?_ŽG~’Jjk1KT.lhDŒƒUhzQ\oMxbHhQ7Q\EXJ>†sVCK6nqN„•mŽ n’Äšƒ¿Œ²‰³{’¿oœ²fv§ZxTtF”]ˆ“i•§_‚©YxEyxHzN—Z£b•€]ŠyUŽŒiŒ°p±Ã~¾ò³Àÿ¶¨íœ´ÙŒ Áx¾©€Šº‡•¡l‡{E¨|R{yY\ƒYr~V¥›]“—jÄŸuÓ£wÍ‚VÊtHÄtMÓ~ZÄ•nºj”šY›˜L›‡J¥Vš€V¾Žc‡~MzkDek7OX3EF/QD1iYI•…ɦ̜n¦~€°…Œ¾„j¥zhÊ›¨ö¹Úÿ¿Þö¼Ïå©“Ò‰e¢kZcf‘jl™o”¶|¸È‹}Áy,R6XVBv”dÎi‹¯W€–@t}:VqEg¦[·jp¤w™¾’”Å•†¯|§}…®”´•¦¸’˜³p’“`¡av=d`8gc8UY0\]?qyVPNFl>&4G"8PoKki~»~ŒË{z³po©d_]X…ji–wl¡wq‘jm”`uVb“FS|L\ƒ^gnnl~‹gh•]U…ANjTx…‡–°ˆ„”le{d[pbVsZNo[cŒl˜¾n‹°`f“[w˜w~§tz©v|¦{~ªmv¤Vl†H`oBVX4RP6WSHk{cuœbu›kw•sˆ¢e}ŽQe‡_|¢g‹§dˆŸS_{INgEdlET^;6>-2F">V/?S5G[5LbC6HR9Hk>=T.NQ(Xd-Ci@EU8Ba-MU2eg6†‹IO`NeIOrPCnN1`4/K./:!7A":'1)C<3G(:C&77P7Vf-NB=vKW_8a>@„P+U@NG+Hj3/b9!JD 3*O:N`&Fa4R`4Kf,T˜h@a@Sm2sw2Y™QAyVHcDQtCF`>hN.ys2i—BfŽ@m‚Q—„Vdº†N†[VhEs‚;a™DSi8„Hz„Vf{W{«jp˜YbuFv‰Jf‰EjoC]lPfnTwxU“nZe—¤d”¶r—ÃsÃy¿{ Kµ€?Ä€;ÿ˜L¯£l¿«‹øÙ½ÿÚ¶††fhlD~tD`q2aY;HSeZFjQ`J5SM2Uh£–j”¨x©gÀ¹¿æ«Þ‘›Íu«¢d¬œ_ÆW§d9ymBƒ‹t€³Žvª€{•pq¬s„Ÿn€ d¢•_•¥m‘Ž^Ÿx[³‰Zš–U¦‡PœŠ_‹£h˜]€“YxIsfEXmL_d?dh>^V9QU7_cXŒ¡Š¨Êœ¸Ê¥ŸÓŸ£ì¥žî ¢â›µêœ¿Ý¢¿ÓŸµß¯²å¿²ä©Ñ“{Ä‚~³~½ƒŒ¸pxeQ¸ zZ¤fQoN}]©²Zs‘:W^&V\4^ZxÄzxºv‰³~£Ä¡È‹ˆ¥my‡cŒ›{Œ±}µ‡y˜WmpH…}Iew;cfAZ`6QM-ZS;geF{…UX‘GV`6JQ.J>0LK/BW6Eo=Dr3\w4ln+H]*DT/A[5@R//A/7836."E6&YD/NI2OD6FX=KhEh„`º„–Ñ|x´n}±eh‹]cˆ[c€WpYmŠ]z§\cOkŠKR†WXŽd]Œkn•rz˜lz‰Wg€EKjEd||’£}j•obbLi_VfZThQi{_’¬fªS_ˆTf^t”fr¤c{£j‰›Xw„QXq5GZ*=> /5 CC/Q]Djƒ[p›am˜`sPcESvGiRv~FhbC`J…xE€KYr< \ No newline at end of file diff --git a/SD-VBS/common/toolbox/lagrcv/test/pathdef.m b/SD-VBS/common/toolbox/lagrcv/test/pathdef.m new file mode 100755 index 0000000..7a33e83 --- /dev/null +++ b/SD-VBS/common/toolbox/lagrcv/test/pathdef.m @@ -0,0 +1,284 @@ +function p = pathdef +%PATHDEF Search path defaults. +% PATHDEF returns a string that can be used as input to MATLABPATH +% in order to set the path. + + +% Copyright 1984-2002 The MathWorks, Inc. +% $Revision: 1.4.2.1 $ $Date: 2003/01/16 12:51:34 $ + + +% DO NOT MODIFY THIS FILE. IT IS AN AUTOGENERATED FILE. +% EDITING MAY CAUSE THE FILE TO BECOME UNREADABLE TO +% THE PATHTOOL AND THE INSTALLER. + +p = [... +%%% BEGIN ENTRIES %%% + '/u/ikkjin/Benchmark:', ... + '/u/ikkjin/Benchmark/viola_jones/src/test:', ... + '/u/ikkjin/Benchmark/viola_jones/src/test/distrib:', ... + '/u/ikkjin/Benchmark/viola_jones/src/test/src:', ... + '/u/ikkjin/Benchmark/Toolbox:', ... + '/u/ikkjin/Benchmark/Toolbox/Gang:', ... + '/u/ikkjin/Benchmark/Toolbox/MultiNcut:', ... + '/u/ikkjin/Benchmark/Toolbox/MultiNcut3D:', ... + '/u/ikkjin/Benchmark/Toolbox/QihuiTool:', ... + '/u/ikkjin/Benchmark/Toolbox/QihuiTool/NNMF:', ... + '/u/ikkjin/Benchmark/Toolbox/QihuiTool/RGB2Lab:', ... + '/u/ikkjin/Benchmark/Toolbox/QihuiTool/SIFT_toolbox:', ... + '/u/ikkjin/Benchmark/Toolbox/QihuiTool/SIFT_toolbox/images:', ... + '/u/ikkjin/Benchmark/Toolbox/ShapeContext:', ... + '/u/ikkjin/Benchmark/Toolbox/ShapeContext/lap:', ... + '/u/ikkjin/Benchmark/Toolbox/ShapeContext/lap/CVS:', ... + '/u/ikkjin/Benchmark/Toolbox/ikkjin:', ... + '/u/ikkjin/Benchmark/Toolbox/interContourCutsAffine:', ... + '/u/ikkjin/Benchmark/Toolbox/interContourCutsAffine/source:', ... + '/u/ikkjin/Benchmark/Toolbox/lagrcv:', ... + '/u/ikkjin/Benchmark/Toolbox/lagrcv/test:', ... + '/u/ikkjin/Benchmark/Toolbox/lagrcv/test/result:', ... + '/u/ikkjin/Benchmark/Toolbox/textons:', ... + '/u/ikkjin/Benchmark/Toolbox/toolbox_basic:', ... + '/u/ikkjin/Benchmark/Toolbox/toolbox_basic/TOOLBOX_calib:', ... + '/u/ikkjin/Benchmark/Toolbox/toolbox_basic/affine:', ... + '/u/ikkjin/Benchmark/Toolbox/toolbox_basic/calib:', ... + '/u/ikkjin/Benchmark/Toolbox/toolbox_basic/calib/TOOLBOX_calib:', ... + '/u/ikkjin/Benchmark/Toolbox/toolbox_basic/calib_bouguetj:', ... + '/u/ikkjin/Benchmark/Toolbox/toolbox_basic/calib_bouguetj2:', ... + '/u/ikkjin/Benchmark/Toolbox/toolbox_basic/common:', ... + '/u/ikkjin/Benchmark/Toolbox/toolbox_basic/disp:', ... + '/u/ikkjin/Benchmark/Toolbox/toolbox_basic/fact:', ... + '/u/ikkjin/Benchmark/Toolbox/toolbox_basic/filter:', ... + '/u/ikkjin/Benchmark/Toolbox/toolbox_basic/filter_hist:', ... + '/u/ikkjin/Benchmark/Toolbox/toolbox_basic/filtersQuad:', ... + '/u/ikkjin/Benchmark/Toolbox/toolbox_basic/io:', ... + '/u/ikkjin/Benchmark/Toolbox/toolbox_basic/matching:', ... + '/u/ikkjin/Benchmark/Toolbox/toolbox_basic/matching/pub:', ... + '/u/ikkjin/Benchmark/Toolbox/toolbox_basic/matching/pub/contrib:', ... + '/u/ikkjin/Benchmark/Toolbox/toolbox_basic/matching/pub/contrib/v5:', ... + '/u/ikkjin/Benchmark/Toolbox/toolbox_basic/matching/pub/contrib/v5/optim:', ... + '/u/ikkjin/Benchmark/Toolbox/toolbox_basic/matching/pub/contrib/v5/optim/assignprob:', ... + '/u/ikkjin/Benchmark/Toolbox/toolbox_basic/ncut:', ... + '/u/ikkjin/Benchmark/Toolbox/toolbox_basic/pyramid:', ... + '/u/ikkjin/Benchmark/Toolbox/toolbox_basic/stella:', ... + '/u/ikkjin/Benchmark/Toolbox/toolbox_basic/tars:', ... + '/u/ikkjin/Benchmark/Toolbox/toolbox_basic/textons:', ... + '/u/ikkjin/Benchmark/color2gray:', ... + '/u/ikkjin/Benchmark/color2gray/src:', ... + '/u/ikkjin/Benchmark/color2gray/src/TestImages:', ... + '/u/ikkjin/Benchmark/color2gray/src/colorspaces:', ... + '/u/ikkjin/Benchmark/color2gray/src/helper:', ... + '/u/ikkjin/Benchmark/disparity:', ... + '/u/ikkjin/Benchmark/disparity/result:', ... + '/u/ikkjin/Benchmark/disparity/src:', ... + '/u/ikkjin/Benchmark/localization:', ... + '/u/ikkjin/Benchmark/localization/result:', ... + '/u/ikkjin/Benchmark/localization/src:', ... + '/u/ikkjin/Benchmark/registration:', ... + '/u/ikkjin/Benchmark/registration/result:', ... + '/u/ikkjin/Benchmark/registration/src:', ... + '/u/ikkjin/Benchmark/stitch:', ... + '/u/ikkjin/Benchmark/stitch/result:', ... + '/u/ikkjin/Benchmark/stitch/src:', ... + '/u/ikkjin/Benchmark/texture_synthesis:', ... + '/u/ikkjin/Benchmark/texture_synthesis/MEX:', ... + '/u/ikkjin/Benchmark/tracking:', ... + '/u/ikkjin/Benchmark/tracking/result:', ... + '/u/ikkjin/Benchmark/tracking/src:', ... + '/u/ikkjin/Benchmark/viola_jones:', ... + '/u/ikkjin/Benchmark/viola_jones/result:', ... + '/u/ikkjin/Benchmark/viola_jones/src:', ... + '/u/ikkjin/Benchmark/viola_jones/src/Additional Functions:', ... + '/u/ikkjin/Benchmark/viola_jones/src/Code:', ... + '/u/ikkjin/Benchmark/viola_jones/src/MatlabFaceDetect Files:', ... + matlabroot,'/toolbox/matlab/general:', ... + matlabroot,'/toolbox/matlab/ops:', ... + matlabroot,'/toolbox/matlab/lang:', ... + matlabroot,'/toolbox/matlab/elmat:', ... + matlabroot,'/toolbox/matlab/elfun:', ... + matlabroot,'/toolbox/matlab/specfun:', ... + matlabroot,'/toolbox/matlab/matfun:', ... + matlabroot,'/toolbox/matlab/datafun:', ... + matlabroot,'/toolbox/matlab/polyfun:', ... + matlabroot,'/toolbox/matlab/funfun:', ... + matlabroot,'/toolbox/matlab/sparfun:', ... + matlabroot,'/toolbox/matlab/scribe:', ... + matlabroot,'/toolbox/matlab/graph2d:', ... + matlabroot,'/toolbox/matlab/graph3d:', ... + matlabroot,'/toolbox/matlab/specgraph:', ... + matlabroot,'/toolbox/matlab/graphics:', ... + matlabroot,'/toolbox/matlab/uitools:', ... + matlabroot,'/toolbox/matlab/strfun:', ... + matlabroot,'/toolbox/matlab/imagesci:', ... + matlabroot,'/toolbox/matlab/iofun:', ... + matlabroot,'/toolbox/matlab/audiovideo:', ... + matlabroot,'/toolbox/matlab/timefun:', ... + matlabroot,'/toolbox/matlab/datatypes:', ... + matlabroot,'/toolbox/matlab/verctrl:', ... + matlabroot,'/toolbox/matlab/codetools:', ... + matlabroot,'/toolbox/matlab/helptools:', ... + matlabroot,'/toolbox/matlab/demos:', ... + matlabroot,'/toolbox/matlab/timeseries:', ... + matlabroot,'/toolbox/matlab/hds:', ... + matlabroot,'/toolbox/matlab/guide:', ... + matlabroot,'/toolbox/matlab/plottools:', ... + matlabroot,'/toolbox/local:', ... + matlabroot,'/toolbox/shared/controllib:', ... + matlabroot,'/toolbox/simulink/simulink:', ... + matlabroot,'/toolbox/simulink/blocks:', ... + matlabroot,'/toolbox/simulink/components:', ... + matlabroot,'/toolbox/simulink/fixedandfloat:', ... + matlabroot,'/toolbox/simulink/fixedandfloat/fxpdemos:', ... + matlabroot,'/toolbox/simulink/fixedandfloat/obsolete:', ... + matlabroot,'/toolbox/simulink/simdemos:', ... + matlabroot,'/toolbox/simulink/simdemos/aerospace:', ... + matlabroot,'/toolbox/simulink/simdemos/automotive:', ... + matlabroot,'/toolbox/simulink/simdemos/simfeatures:', ... + matlabroot,'/toolbox/simulink/simdemos/simgeneral:', ... + matlabroot,'/toolbox/simulink/dee:', ... + matlabroot,'/toolbox/shared/dastudio:', ... + matlabroot,'/toolbox/shared/glue:', ... + matlabroot,'/toolbox/stateflow/stateflow:', ... + matlabroot,'/toolbox/rtw/rtw:', ... + matlabroot,'/toolbox/simulink/simulink/modeladvisor:', ... + matlabroot,'/toolbox/simulink/simulink/modeladvisor/fixpt:', ... + matlabroot,'/toolbox/simulink/simulink/MPlayIO:', ... + matlabroot,'/toolbox/simulink/simulink/dataobjectwizard:', ... + matlabroot,'/toolbox/shared/fixedpointlib:', ... + matlabroot,'/toolbox/simulink/dataimportexport:', ... + matlabroot,'/toolbox/shared/hdlshared:', ... + matlabroot,'/toolbox/rtw/rtwdemos:', ... + matlabroot,'/toolbox/rtw/rtwdemos/rsimdemos:', ... + matlabroot,'/toolbox/rtw/targets/asap2/asap2:', ... + matlabroot,'/toolbox/rtw/targets/asap2/asap2/user:', ... + matlabroot,'/toolbox/rtw/targets/common/can/blocks:', ... + matlabroot,'/toolbox/rtw/targets/common/configuration/resource:', ... + matlabroot,'/toolbox/rtw/targets/common/tgtcommon:', ... + matlabroot,'/toolbox/stateflow/sfdemos:', ... + matlabroot,'/toolbox/stateflow/coder:', ... + matlabroot,'/toolbox/bioinfo/bioinfo:', ... + matlabroot,'/toolbox/bioinfo/biolearning:', ... + matlabroot,'/toolbox/bioinfo/microarray:', ... + matlabroot,'/toolbox/bioinfo/mass_spec:', ... + matlabroot,'/toolbox/bioinfo/proteins:', ... + matlabroot,'/toolbox/bioinfo/biomatrices:', ... + matlabroot,'/toolbox/bioinfo/biodemos:', ... + matlabroot,'/toolbox/bioinfo/graphtheory:', ... + matlabroot,'/toolbox/commblks/commblks:', ... + matlabroot,'/toolbox/commblks/commmasks:', ... + matlabroot,'/toolbox/commblks/commmex:', ... + matlabroot,'/toolbox/commblks/commblksdemos:', ... + matlabroot,'/toolbox/commblks/commblksobsolete/v3:', ... + matlabroot,'/toolbox/commblks/commblksobsolete/v2p5:', ... + matlabroot,'/toolbox/commblks/commblksobsolete/v2:', ... + matlabroot,'/toolbox/comm/comm:', ... + matlabroot,'/toolbox/comm/commdemos:', ... + matlabroot,'/toolbox/comm/commdemos/commdocdemos:', ... + matlabroot,'/toolbox/comm/commobsolete:', ... + matlabroot,'/toolbox/compiler:', ... + matlabroot,'/toolbox/control/control:', ... + matlabroot,'/toolbox/control/ctrlguis:', ... + matlabroot,'/toolbox/control/ctrlobsolete:', ... + matlabroot,'/toolbox/control/ctrlutil:', ... + matlabroot,'/toolbox/control/ctrldemos:', ... + matlabroot,'/toolbox/shared/slcontrollib:', ... + matlabroot,'/toolbox/curvefit/curvefit:', ... + matlabroot,'/toolbox/curvefit/cftoolgui:', ... + matlabroot,'/toolbox/shared/optimlib:', ... + matlabroot,'/toolbox/dspblks/dspblks:', ... + matlabroot,'/toolbox/dspblks/dspmasks:', ... + matlabroot,'/toolbox/dspblks/dspmex:', ... + matlabroot,'/toolbox/dspblks/dspdemos:', ... + matlabroot,'/toolbox/shared/filterdesignlib:', ... + matlabroot,'/toolbox/rtw/targets/ecoder:', ... + matlabroot,'/toolbox/rtw/targets/ecoder/ecoderdemos:', ... + matlabroot,'/toolbox/rtw/targets/mpt:', ... + matlabroot,'/toolbox/rtw/targets/mpt/mpt:', ... + matlabroot,'/toolbox/rtw/targets/mpt/user_specific:', ... + matlabroot,'/toolbox/fixedpoint/fixedpoint:', ... + matlabroot,'/toolbox/fixedpoint/fidemos:', ... + matlabroot,'/toolbox/fixedpoint/fimex:', ... + matlabroot,'/toolbox/fixpoint:', ... + matlabroot,'/toolbox/gads:', ... + matlabroot,'/toolbox/gads/gads:', ... + matlabroot,'/toolbox/gads/gadsdemos:', ... + matlabroot,'/toolbox/ident/ident:', ... + matlabroot,'/toolbox/ident/idobsolete:', ... + matlabroot,'/toolbox/ident/idguis:', ... + matlabroot,'/toolbox/ident/idutils:', ... + matlabroot,'/toolbox/ident/iddemos:', ... + matlabroot,'/toolbox/ident/idhelp:', ... + matlabroot,'/toolbox/images/images:', ... + matlabroot,'/toolbox/images/imuitools:', ... + matlabroot,'/toolbox/images/imdemos:', ... + matlabroot,'/toolbox/images/iptutils:', ... + matlabroot,'/toolbox/shared/imageslib:', ... + matlabroot,'/toolbox/images/medformats:', ... + matlabroot,'/toolbox/instrument/instrument:', ... + matlabroot,'/toolbox/instrument/instrumentdemos:', ... + matlabroot,'/toolbox/map/map:', ... + matlabroot,'/toolbox/map/mapdemos:', ... + matlabroot,'/toolbox/map/mapdisp:', ... + matlabroot,'/toolbox/map/mapformats:', ... + matlabroot,'/toolbox/map/mapproj:', ... + matlabroot,'/toolbox/shared/mapgeodesy:', ... + matlabroot,'/toolbox/slvnv/simcoverage:', ... + matlabroot,'/toolbox/nnet:', ... + matlabroot,'/toolbox/nnet/nncontrol:', ... + matlabroot,'/toolbox/nnet/nndemos:', ... + matlabroot,'/toolbox/nnet/nnet:', ... + matlabroot,'/toolbox/nnet/nnet/nnanalyze:', ... + matlabroot,'/toolbox/nnet/nnet/nncustom:', ... + matlabroot,'/toolbox/nnet/nnet/nndistance:', ... + matlabroot,'/toolbox/nnet/nnet/nnformat:', ... + matlabroot,'/toolbox/nnet/nnet/nninit:', ... + matlabroot,'/toolbox/nnet/nnet/nnlearn:', ... + matlabroot,'/toolbox/nnet/nnet/nnnetinput:', ... + matlabroot,'/toolbox/nnet/nnet/nnnetwork:', ... + matlabroot,'/toolbox/nnet/nnet/nnperformance:', ... + matlabroot,'/toolbox/nnet/nnet/nnplot:', ... + matlabroot,'/toolbox/nnet/nnet/nnprocess:', ... + matlabroot,'/toolbox/nnet/nnet/nnsearch:', ... + matlabroot,'/toolbox/nnet/nnet/nntopology:', ... + matlabroot,'/toolbox/nnet/nnet/nntrain:', ... + matlabroot,'/toolbox/nnet/nnet/nntransfer:', ... + matlabroot,'/toolbox/nnet/nnet/nnweight:', ... + matlabroot,'/toolbox/nnet/nnguis:', ... + matlabroot,'/toolbox/nnet/nnguis/nftool:', ... + matlabroot,'/toolbox/nnet/nnguis/nntool:', ... + matlabroot,'/toolbox/nnet/nnobsolete:', ... + matlabroot,'/toolbox/nnet/nnresource:', ... + matlabroot,'/toolbox/nnet/nnutils:', ... + matlabroot,'/toolbox/optim:', ... + matlabroot,'/toolbox/pde:', ... + matlabroot,'/toolbox/robust/robust:', ... + matlabroot,'/toolbox/robust/rctlmi:', ... + matlabroot,'/toolbox/robust/rctutil:', ... + matlabroot,'/toolbox/robust/rctdemos:', ... + matlabroot,'/toolbox/robust/rctobsolete/robust:', ... + matlabroot,'/toolbox/robust/rctobsolete/lmi:', ... + matlabroot,'/toolbox/robust/rctobsolete/mutools/commands:', ... + matlabroot,'/toolbox/robust/rctobsolete/mutools/subs:', ... + matlabroot,'/toolbox/signal/signal:', ... + matlabroot,'/toolbox/signal/sigtools:', ... + matlabroot,'/toolbox/signal/sptoolgui:', ... + matlabroot,'/toolbox/signal/sigdemos:', ... + matlabroot,'/toolbox/shared/spcuilib:', ... + matlabroot,'/toolbox/slcontrol/slcontrol:', ... + matlabroot,'/toolbox/slcontrol/slctrlguis:', ... + matlabroot,'/toolbox/slcontrol/slctrlutil:', ... + matlabroot,'/toolbox/slcontrol/slctrldemos:', ... + matlabroot,'/toolbox/splines:', ... + matlabroot,'/toolbox/stats:', ... + matlabroot,'/toolbox/vipblks/vipblks:', ... + matlabroot,'/toolbox/vipblks/vipmasks:', ... + matlabroot,'/toolbox/vipblks/vipmex:', ... + matlabroot,'/toolbox/vipblks/vipdemos:', ... + matlabroot,'/toolbox/wavelet/wavelet:', ... + matlabroot,'/toolbox/wavelet/wmultisig1d:', ... + matlabroot,'/toolbox/wavelet/wavedemo:', ... + matlabroot,'/work:', ... +%%% END ENTRIES %%% + ... +]; + +p = [userpath,p]; diff --git a/SD-VBS/common/toolbox/lagrcv/test/test_lk.m b/SD-VBS/common/toolbox/lagrcv/test/test_lk.m new file mode 100755 index 0000000..c6ca701 --- /dev/null +++ b/SD-VBS/common/toolbox/lagrcv/test/test_lk.m @@ -0,0 +1,74 @@ +addpath ~/Matlab/Toolbox/lagrcv/ +addpath ~/Matlab/Toolbox/toolbox_basic/filter +addpath ~/Matlab/Toolbox/ikkjin/ + +N_FEA=1600; +WINSZ=8; %size of sum-up window +NO_PYR=2; +SUPPRESION_RADIUS=10; +LK_ITER=20; +IMAGE_DIR='~/backup/Research/ant/Transport/' +filelist=dir(fullfile(IMAGE_DIR, '*.jpg')); +flen=length(filelist); + +img_idx_cur=[1:flen]; + +%subplot(1,2,1);imshow(Iprev) +%/hold on +%//scatter(features(2,:),features(1,:),'r') +%% +imgName=fullfile(IMAGE_DIR,filelist(img_idx_cur(1)).name); +Icur=imread(imgName); +Icur=rgb2gray(Icur); +Icur=calcImgBlurMex(double(Icur)); +%% + +Jpyr=getPyramid(Icur, 2); + +[lambda tr det c_xx c_xy c_yy] =calcTextureMex(double(Icur), WINSZ); +imgsz=size(lambda); +lambda([1:8 end-8:end],:)=0; +lambda(:,[1:8 end-8:end])=0; +[temp idx]=sort(lambda(:), 'descend'); + +%% +featureIdx=idx(1:N_FEA); +features=zeros(3, N_FEA); +features(1,:)=ceil(featureIdx/imgsz(1)); +features(2,:)=featureIdx'-(features(1,:)-1)*imgsz(1); +features(3,:)=lambda(featureIdx); + +imagesc(lambda); hold on +scatter(features(1,:), features(2,:), 'r+');hold off +%% +interestPnt=getANMS(features(1,:)', features(2,:)', features(3,:)', SUPPRESION_RADIUS); +interestPnt=interestPnt'; +scatter(interestPnt(1,:), interestPnt(2,:), 'g+') +%% +features=interestPnt(1:2,:); +%% + +for iter=img_idx_cur + Iprev=Icur; + Icur=imread(fullfile(IMAGE_DIR,filelist(img_idx_cur(iter)).name)); + Icur=rgb2gray(Icur); + Icur=calcImgBlurMex(double(Icur)); + + Ipyr=Jpyr; + Jpyr=getPyramid(Icur, 2); + + [dxPyr dyPyr]=calcSobelPyrMex(Ipyr,2); + + [lambda tr det c_xx c_xy c_yy] = calcTexturePyrMex(dxPyr, dyPyr, WINSZ, NO_PYR); + + [newpoints status]=calcOptFlowLKPyrMex(Ipyr, dxPyr, dyPyr, Jpyr, double(features), 4, 0.03, LK_ITER, c_xx, c_xy, c_yy); + + newpoints=newpoints(:,find(status)); + figure(1); + imagesc(Icur);colormap gray + hold on;scatter(newpoints(1,:), newpoints(2,:), 'r+'); hold off; + drawnow + %print('-djpeg', sprintf('result/result_%03d', iter)) + %pause + features=newpoints; +end diff --git a/SD-VBS/common/toolbox/lagrcv/test/test_lk_disp.m b/SD-VBS/common/toolbox/lagrcv/test/test_lk_disp.m new file mode 100755 index 0000000..2d55fe3 --- /dev/null +++ b/SD-VBS/common/toolbox/lagrcv/test/test_lk_disp.m @@ -0,0 +1,49 @@ +addpath /u/ikkjin/Matlab/Toolbox/lagrcv + +%Iprev=imread('/Projects/LAGR/logs/Test5/left_APIrun530-1/l24Aug05-abacination-1124876208.403311.ppm'); +%Icur=imread('/Projects/LAGR/logs/Test5/left_APIrun530-1/l24Aug05-abacination-1124876208.670013.ppm'); +Iprev=imread('img0.ppm'); +Icur=imread('img1.ppm'); + +Iprev=rgb2gray(Iprev); +Icur=rgb2gray(Icur); + +tic + [ features numvalid ] = goodFeaturesToTrack(Iprev, 0.3, 10); +toc +subplot(1,2,1);imshow(Iprev) +hold on +scatter(features(2,:),features(1,:),'r') + +Ipyr=getPyramid(Iprev, 3); +Jpyr=getPyramid(Icur, 3); +tic +[dxPyr2 dyPyr2]=calcGradientPyrMex(Ipyr,3); +toc +tic +[dxPyr dyPyr]=calcSobelPyrMex(Ipyr,3); +toc + +features=features(:,1:211); +for i=20 + features2=[features(2,:); features(1,:)]; +tic + [ newpoints status pyr1 ] = calcOpticalFlowPyrLK(Iprev,Icur,features, i); +toc +tic + [newpoints2 status]=calcOptFlowLKPyrMex(Ipyr, dxPyr, dyPyr, Jpyr, double(features2), 4, 0.03, i); +toc + newpoints2=[newpoints2(2,:); newpoints2(1,:)]; +features_out=features(:,find(status)); +newpoints=newpoints(:,find(status)); +newpoints2=newpoints2(:,find(status)); +subplot(1,2,1);imshow(Iprev);hold on +quiver(features_out(2,:),features_out(1,:), newpoints(2,:)-features_out(2,:), newpoints(1,:)-features_out(1,:),0,'r');hold off +subplot(1,2,2);imshow(Iprev);hold on +quiver(features_out(2,:),features_out(1,:), newpoints2(2,:)-features_out(2,:), newpoints2(1,:)-features_out(1,:),0,'r');hold off +%subplot(1,2,2);imshow(Icur);hold on +%scatter(newpoints2(2,:),newpoints2(1,:),'r');hold off +%sum(sum((newpoints-newpoints2).^2)) + +pause +end diff --git a/SD-VBS/common/toolbox/lagrcv/test/test_lk_opencv.m b/SD-VBS/common/toolbox/lagrcv/test/test_lk_opencv.m new file mode 100755 index 0000000..9cfd1ae --- /dev/null +++ b/SD-VBS/common/toolbox/lagrcv/test/test_lk_opencv.m @@ -0,0 +1,47 @@ +addpath ~/Matlab/Toolbox/lagrcv/ +addpath ~/Matlab/Toolbox/toolbox_basic/filter +addpath ~/Matlab/Toolbox/ikkjin/ + +IMAGE_DIR='/data/insecure/images/ants/Transport/' +filelist=dir(fullfile(IMAGE_DIR, '*.jpg')); +flen=length(filelist); + +img_idx_cur=[1:flen]; + +%subplot(1,2,1);imshow(Iprev) +%/hold on +%//scatter(features(2,:),features(1,:),'r') +%Iprev=imread(fullfile(IMAGE_DIR,filelist(img_idx_prev(1)).name)); +%% +imgName=fullfile(IMAGE_DIR,filelist(img_idx_cur(1)).name); +Icur=imread(imgName); +%% +Icur=smooth(double(rgb2gray(Icur)), 4); +%% +Icur=Icur(1:2:end,1:2:end); + +[ features numvalid ] = goodFeaturesToTrack(Icur, 0.3, 10); +features=features(:,1:numvalid); + +figure(1); +imagesc(Icur);colormap gray +hold on;scatter(features(2,:), features(1,:), 'r+'); hold off; + +%% +for iter=img_idx_cur + Iprev=Icur; + Icur=imread(fullfile(IMAGE_DIR,filelist(img_idx_cur(iter)).name)); + Icur=calcImgBlurMex(rgb2gray(Icur)); + + tic + [ newpoints status pyr1 ] = calcOpticalFlowPyrLK(Iprev,Icur,features); + toc + newpoints=newpoints(:,find(status)); + figure(1); + imagesc(Icur);colormap gray + hold on;scatter(newpoints(2,:), newpoints(1,:), 'r+'); hold off; + drawnow + print('-djpeg', sprintf('result/result_%03d', iter)) + %pause + features=newpoints; +end diff --git a/SD-VBS/common/toolbox/mex_template.c b/SD-VBS/common/toolbox/mex_template.c new file mode 100755 index 0000000..b85683f --- /dev/null +++ b/SD-VBS/common/toolbox/mex_template.c @@ -0,0 +1,58 @@ +//function W = mex_template(X,Y); + +#include +#include +//#include +//#include "mex_util.cpp" + +//#define PI 3.1415927 + +void mexFunction(int nargout, mxArray *out[], int nargin, const mxArray +*in[]) { + //reading in + const mxArray *X = in[0]; + double *pr = mxGetPr(X); + int *ir = mxGetIr(X); + int *jc = mxGetJc(X); + int m = mxGetM(X); + int n = mxGetN(X); + + mxArray *cell_1 = mxGetCell(cell_input,0); + mxGetData() + mxGetNumberOfDimensions() + mxGetDimensions() + mxGetNumberOfElements() + + //sparse array reading + int i,j,k; + double x; + for (j=0;j0.1)&~two_focal, + disp('Should use two focals in x and y...'); +end; + +% Deduce the translation vector: + +Tc_2 = distance * H_2; + + + + + +return; + + V_hori_pix/V_hori_pix(3) + V_vert_pix/V_vert_pix(3) + V_diag1_pix/V_diag1_pix(3) + V_diag2_pix/V_diag2_pix(3) diff --git a/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/Rectangle2Square.m b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/Rectangle2Square.m new file mode 100755 index 0000000..a6bbbe5 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/Rectangle2Square.m @@ -0,0 +1,19 @@ +function [square] = Rectangle2Square(rectangle,L,W); + +% Generate the square from a rectangle of known segment lengths +% from pt1 to pt2 : L +% from pt2 to pt3 : W + +[u_hori,u_vert] = UnWarpPlane(rectangle); + +coeff_x = sqrt(W/L); +coeff_y = 1/coeff_x; + +x_coord = [ 0 coeff_x coeff_x 0]; +y_coord = [ 0 0 coeff_y coeff_y]; + + +square = rectangle(:,1) * ones(1,4) + u_hori*x_coord + u_vert*y_coord; +square = square ./ (ones(3,1)*square(3,:)); + + diff --git a/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/UnWarpPlane.m b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/UnWarpPlane.m new file mode 100755 index 0000000..8addf52 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/UnWarpPlane.m @@ -0,0 +1,54 @@ +function [u_hori,u_vert] = UnWarpPlane(x1,x2,x3,x4); + +% Recovers the two 3D directions of the rectangular patch x1x2x3x4 +% x1 is the origin point, ie any point of planar coordinate (x,y) on the +% rectangular patch will be projected on the image plane at: +% x1 + x * u_hori + y * u_vert +% +% Note: u_hori and u_vert are also the two vanishing points. + + +if nargin < 4, + + x4 = x1(:,4); + x3 = x1(:,3); + x2 = x1(:,2); + x1 = x1(:,1); + +end; + + +% Image Projection: +L1 = cross(x1,x2); +L2 = cross(x4,x3); +L3 = cross(x2,x3); +L4 = cross(x1,x4); + +% Vanishing point: +V1 = cross(L1,L2); +V2 = cross(L3,L4); + +% Horizon line: +H = cross(V1,V2); + +if H(3) < 0, H = -H; end; + + +H = H / norm(H); + + +X1 = x1 / dot(H,x1); +X2 = x2 / dot(H,x2); +X3 = x3 / dot(H,x3); +X4 = x4 / dot(H,x4); + +scale = X1(3); + +X1 = X1/scale; +X2 = X2/scale; +X3 = X3/scale; +X4 = X4/scale; + + +u_hori = X2 - X1; +u_vert = X4 - X1; diff --git a/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/add_suppress.m b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/add_suppress.m new file mode 100755 index 0000000..a8a32c0 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/add_suppress.m @@ -0,0 +1,98 @@ + +if ~exist('n_ima'), + fprintf(1,'No data to process.\n'); + return; +end; + + +check_active_images; + + +fprintf(1,'\nThis function is useful to select a subset of images to calibrate\n'); + + fprintf(1,'\nThere are currently %d active images selected for calibration (out of %d):\n',length(ind_active),n_ima); + + if ~isempty(ind_active), + + for ii = 1:length(ind_active)-2, + + fprintf(1,'%d, ',ind_active(ii)); + + end; + + fprintf(1,'%d and %d.',ind_active(end-1),ind_active(end)); + + end; + + fprintf(1,'\n'); + + +fprintf(1,'\nDo you want to suppress or add images from that list?\n'); + +choice = 2; + +while (choice~=0)&(choice~=1), + choice = input('For suppressing images enter 0, for adding images enter 1 ([]=no change): '); + if isempty(choice), + fprintf(1,'No change applied to the list of active images.\n'); + return; + end; + if (choice~=0)&(choice~=1), + disp('Bad entry. Try again.'); + end; +end; + + +if choice, + + ima_numbers = input('Number(s) of image(s) to add ([] = all images) = '); + +if isempty(ima_numbers), + fprintf(1,'All %d images are now active\n',n_ima); + ima_proc = 1:n_ima; + else + ima_proc = ima_numbers; + end; + +else + + + ima_numbers = input('Number(s) of image(s) to suppress ([] = no image) = '); + + if isempty(ima_numbers), + fprintf(1,'No image has been suppressed. No modication of the list of active images.\n',n_ima); + ima_proc = []; + else + ima_proc = ima_numbers; + end; + +end; + +if ~isempty(ima_proc), + + active_images(ima_proc) = choice * ones(1,length(ima_proc)); + +end; + + + check_active_images; + + + fprintf(1,'\nThere is now a total of %d active images for calibration:\n',length(ind_active)); + + if ~isempty(ind_active), + + for ii = 1:length(ind_active)-2, + + fprintf(1,'%d, ',ind_active(ii)); + + end; + + fprintf(1,'%d and %d.',ind_active(end-1),ind_active(end)); + + end; + + fprintf(1,'\n\nYou may now run ''Calibration'' to recalibrate based on this new set of images.\n'); + + + \ No newline at end of file diff --git a/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/analyse_error.m b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/analyse_error.m new file mode 100755 index 0000000..7a9cf0f --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/analyse_error.m @@ -0,0 +1,141 @@ +% Color code for each image: + +if ~exist('n_ima')|~exist('fc'), + fprintf(1,'No calibration data available.\n'); + return; +end; + +check_active_images; + +if ~exist(['ex_' num2str(ind_active(1)) ]), + fprintf(1,'Need to calibrate before analysing reprojection error. Maybe need to load Calib_Results.mat file.\n'); + return; +end; + + +%if ~exist('no_grid'), + no_grid = 0; +%end; + +colors = 'brgkcm'; + + +figure(5); + +for kk = 1:n_ima, + if exist(['y_' num2str(kk)]), + if active_images(kk) & eval(['~isnan(y_' num2str(kk) '(1,1))']), + + if ~no_grid, + eval(['XX_kk = X_' num2str(kk) ';']); + N_kk = size(XX_kk,2); + + if ~exist(['n_sq_x_' num2str(kk)]), + no_grid = 1; + end; + + if ~no_grid, + eval(['n_sq_x = n_sq_x_' num2str(kk) ';']); + eval(['n_sq_y = n_sq_y_' num2str(kk) ';']); + if (N_kk ~= ((n_sq_x+1)*(n_sq_y+1))), + no_grid = 1; + end; + end; + end; + + eval(['plot(ex_' num2str(kk) '(1,:),ex_' num2str(kk) '(2,:),''' colors(rem(kk-1,6)+1) '+'');']); + + hold on; + end; + end; +end; + +hold off; +axis('equal'); +if 1, %~no_grid, + title('Reprojection error (in pixel) - To exit: right button'); +else + title('Reprojection error (in pixel)'); +end; +xlabel('x'); +ylabel('y'); + +set(5,'Name','error','NumberTitle','off'); + + + +err_std = std(ex')'; + +fprintf(1,'Pixel error: err = [ %3.5f %3.5f] (all active images)\n\n',err_std); + + +b = 1; + +while b==1, + +[xp,yp,b] = ginput3(1); + +if b==1, +ddd = (ex(1,:)-xp).^2 + (ex(2,:)-yp).^2; + +[mind,indmin] = min(ddd); + + +done = 0; +kk_ima = 1; +while (~done)&(kk_ima<=n_ima), + %fprintf(1,'%d...',kk_ima); + eval(['ex_kk = ex_' num2str(kk_ima) ';']); + sol_kk = find((ex_kk(1,:) == ex(1,indmin))&(ex_kk(2,:) == ex(2,indmin))); + if isempty(sol_kk), + kk_ima = kk_ima + 1; + else + done = 1; + end; +end; + +if ~no_grid, + +eval(['n_sq_x = n_sq_x_' num2str(kk_ima) ';']); +eval(['n_sq_y = n_sq_y_' num2str(kk_ima) ';']); + +Nx = n_sq_x+1; +Ny = n_sq_y+1; + +y1 = floor((sol_kk-1)./Nx); +x1 = sol_kk - 1 - Nx*y1; %rem(sol_kk-1,Nx); + +y1 = (n_sq_y+1) - y1; +x1 = x1 + 1; + +fprintf(1,'\nSelected image: %d\nSelected point: (col,row)=(%d,%d)\nNcol=%d, Nrow=%d\n',[kk_ima x1 y1 Nx Ny]); +fprintf(1,'Pixel error = (%3.5f,%3.5f)\n',[ex(1,indmin) ex(2,indmin)]); + +else + + eval(['x_kk = x_' num2str(kk_ima) ';']); + + xpt = x_kk(:,sol_kk); + +fprintf(1,'\nSelected image: %d\nImage coordinates (in pixel): (%3.2f,%3.2f)\n',[kk_ima xpt']); +fprintf(1,'Pixel error = (%3.5f,%3.5f)\n',[ex(1,indmin) ex(2,indmin)]); + + +end; + + +if exist(['wintx_' num2str(kk_ima)]), + + eval(['wintx = wintx_' num2str(kk_ima) ';']); + eval(['winty = winty_' num2str(kk_ima) ';']); + + fprintf(1,'Window size: wintx = %d, winty = %d\n',[wintx winty]); +end; + + +end; + +end; + +disp('done'); + diff --git a/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/apply_distortion.m b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/apply_distortion.m new file mode 100755 index 0000000..f5c5b48 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/apply_distortion.m @@ -0,0 +1,137 @@ +function [xd,dxddk] = apply_distortion(x,k) + + +[m,n] = size(x); + +% Add distortion: + +r2 = x(1,:).^2 + x(2,:).^2; + +r4 = r2.^2; + +% Radial distortion: + +cdist = 1 + k(1) * r2 + k(2) * r4; + +if nargout > 1, + dcdistdk = [ r2' r4' zeros(n,2)]; +end; + + +xd1 = x .* (ones(2,1)*cdist); + +coeff = (reshape([cdist;cdist],2*n,1)*ones(1,3)); + +if nargout > 1, + dxd1dk = zeros(2*n,4); + dxd1dk(1:2:end,:) = (x(1,:)'*ones(1,4)) .* dcdistdk; + dxd1dk(2:2:end,:) = (x(2,:)'*ones(1,4)) .* dcdistdk; +end; + + +% tangential distortion: + +a1 = 2.*x(1,:).*x(2,:); +a2 = r2 + 2*x(1,:).^2; +a3 = r2 + 2*x(2,:).^2; + +delta_x = [k(3)*a1 + k(4)*a2 ; + k(3) * a3 + k(4)*a1]; + +aa = (2*k(3)*x(2,:)+6*k(4)*x(1,:))'*ones(1,3); +bb = (2*k(3)*x(1,:)+2*k(4)*x(2,:))'*ones(1,3); +cc = (6*k(3)*x(2,:)+2*k(4)*x(1,:))'*ones(1,3); + +if nargout > 1, + ddelta_xdk = zeros(2*n,4); + ddelta_xdk(1:2:end,3) = a1'; + ddelta_xdk(1:2:end,4) = a2'; + ddelta_xdk(2:2:end,3) = a3'; + ddelta_xdk(2:2:end,4) = a1'; +end; + +xd = xd1 + delta_x; + +if nargout > 1, + dxddk = dxd1dk + ddelta_xdk ; +end; + + +return; + +% Test of the Jacobians: + +n = 10; + +X = 10*randn(3,n); +om = randn(3,1); +T = [10*randn(2,1);40]; +f = 1000*rand(2,1); +c = 1000*randn(2,1); +k = 0.5*randn(4,1); + + +[x,dxdom,dxdT,dxdf,dxdc,dxdk] = project_points(X,om,T,f,c,k); + + +% Test on om: NOT OK + +dom = 0.000000001 * norm(om)*randn(3,1); +om2 = om + dom; + +[x2] = project_points(X,om2,T,f,c,k); + +x_pred = x + reshape(dxdom * dom,2,n); + + +norm(x2-x)/norm(x2 - x_pred) + + +% Test on T: OK!! + +dT = 0.0001 * norm(T)*randn(3,1); +T2 = T + dT; + +[x2] = project_points(X,om,T2,f,c,k); + +x_pred = x + reshape(dxdT * dT,2,n); + + +norm(x2-x)/norm(x2 - x_pred) + + + +% Test on f: OK!! + +df = 0.001 * norm(f)*randn(2,1); +f2 = f + df; + +[x2] = project_points(X,om,T,f2,c,k); + +x_pred = x + reshape(dxdf * df,2,n); + + +norm(x2-x)/norm(x2 - x_pred) + + +% Test on c: OK!! + +dc = 0.01 * norm(c)*randn(2,1); +c2 = c + dc; + +[x2] = project_points(X,om,T,f,c2,k); + +x_pred = x + reshape(dxdc * dc,2,n); + +norm(x2-x)/norm(x2 - x_pred) + +% Test on k: OK!! + +dk = 0.001 * norm(4)*randn(4,1); +k2 = k + dk; + +[x2] = project_points(X,om,T,f,c,k2); + +x_pred = x + reshape(dxdk * dk,2,n); + +norm(x2-x)/norm(x2 - x_pred) diff --git a/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/calib_gui.m b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/calib_gui.m new file mode 100755 index 0000000..d591d03 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/calib_gui.m @@ -0,0 +1,117 @@ +fig_number = 1; + +n_row = 4; +n_col = 4; + +string_list = cell(n_row,n_col); +callback_list = cell(n_row,n_col); + +x_size = 85; +y_size = 14; +gap_x = 0; +font_name = 'clean'; +font_size = 8; + +title_figure = 'Camera Calibration Toolbox'; + +string_list{1,1} = 'Image names'; +string_list{1,2} = 'Read images'; +string_list{1,3} = 'Extract grid corners'; +string_list{1,4} = 'Calibration'; +string_list{2,1} = 'Show Extrinsic'; +string_list{2,2} = 'Reproject on images'; +string_list{2,3} = 'Analyse error'; +string_list{2,4} = 'Recomp. corners'; +string_list{3,1} = 'Add/Suppress images'; +string_list{3,2} = 'Save'; +string_list{3,3} = 'Load'; +string_list{3,4} = 'Exit'; + +string_list{4,1} = 'Comp. Extrinsic'; +string_list{4,2} = 'Undistort image'; +string_list{4,3} = 'Export calib data'; + + +callback_list{1,1} = 'data_calib;'; +callback_list{1,2} = 'ima_read_calib;'; +callback_list{1,3} = 'click_calib;'; +callback_list{1,4} = 'go_calib_optim;'; +callback_list{2,1} = 'ext_calib;'; +callback_list{2,2} = 'reproject_calib;'; +callback_list{2,3} = 'analyse_error;'; +callback_list{2,4} = 'recomp_corner_calib;'; +callback_list{3,1} = 'add_suppress;'; +callback_list{3,2} = 'saving_calib;'; +callback_list{3,3} = 'loading_calib;'; +callback_list{3,4} = ['disp(''Bye. To run again, type calib_gui.''); close(' num2str(fig_number) ');']; + +callback_list{4,1} = 'extrinsic_computation;'; +callback_list{4,2} = 'undistort_image;'; +callback_list{4,3} = 'export_calib_data;'; + + +%------- BEGIN PROECTED REGION -----------% +%------- DO NOT EDIT IN THIS REGION -----------% + +figure(fig_number); clf; +pos = get(fig_number,'Position'); + +fig_size_x = x_size*n_col+(n_col+1)*gap_x; +fig_size_y = y_size*n_row+(n_row+1)*gap_x; + +set(fig_number,'Units','points', ... + 'BackingStore','off', ... + 'Color',[0.8 0.8 0.8], ... + 'MenuBar','none', ... + 'Resize','off', ... + 'Name',title_figure, ... +'Position',[pos(1) pos(2) fig_size_x fig_size_y], ... +'NumberTitle','off'); %,'WindowButtonMotionFcn',['figure(' num2str(fig_number) ');']); + +h_mat = zeros(n_row,n_col); + +posx = zeros(n_row,n_col); +posy = zeros(n_row,n_col); + +for i=n_row:-1:1, + for j = n_col:-1:1, + posx(i,j) = gap_x+(j-1)*(x_size+gap_x); + posy(i,j) = fig_size_y - i*(gap_x+y_size); + end; +end; + +for i=n_row:-1:1, + for j = n_col:-1:1, + if ~isempty(string_list{i,j}) & ~isempty(callback_list{i,j}), + h_mat(i,j) = uicontrol('Parent',fig_number, ... + 'Units','points', ... + 'Callback',callback_list{i,j}, ... + 'ListboxTop',0, ... + 'Position',[posx(i,j) posy(i,j) x_size y_size], ... + 'String',string_list{i,j}, ... + 'fontsize',font_size,... + 'fontname',font_name,... + 'Tag','Pushbutton1'); + end; + end; +end; + +%------ END PROTECTED REGION ----------------% + +if 0, +%-- VERSION: + +uicontrol('Parent',fig_number, ... + 'Units','points', ... + 'ListboxTop',0, ... + 'Position',[(fig_size_x-x_size/2)-2 -5 x_size/2 y_size], ... + 'String','ver. 1.0', ... + 'fontsize',8,... + 'BackgroundColor',[0.8 0.8 0.8], ... + 'fontname','clean',... + 'HorizontalAlignment','right', ... + 'Style','text'); +end; + + +%clear callback_list string_list fig_number fig_size_x fig_size_y i j n_col n_row pos string_list title_figure x_size y_size font_name font_size gap_x h_mat posx posy diff --git a/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/check_active_images.m b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/check_active_images.m new file mode 100755 index 0000000..fc365a5 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/check_active_images.m @@ -0,0 +1,19 @@ + +if ~exist('active_images'), + active_images = ones(1,n_ima); +end; +n_act = length(active_images); +if n_act < n_ima, + active_images = [active_images ones(1,n_ima-n_act)]; +else + if n_act > n_ima, + active_images = active_images(1:n_ima); + end; +end; + +ind_active = find(active_images); + +if prod(active_images == 0), + disp('Error: There is no active image'); + break +end; diff --git a/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/check_convergence.m b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/check_convergence.m new file mode 100755 index 0000000..c4b13fd --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/check_convergence.m @@ -0,0 +1,48 @@ +%%% Replay the set of solution vectors: + + +if ~exist('param_list'), + if ~exist('solution'); + fprintf(1,'Error: Need to calibrate first\n'); + return; + else + param_list = solution; + end; +end; + +N_iter = size(param_list,2); + +if N_iter == 1, + fprintf(1,'Warning: There is a unique state in the list of parameters.\n'); +end; + + + +%M = moviein(N_iter); + +for nn = 1:N_iter, + + solution = param_list(:,nn); + + extract_parameters; + comp_error_calib; + + ext_calib; + + drawnow; + +% Mnn = getframe(gcf); + +% M(:,nn) = Mnn; + +end; + +%fig = gcf; + + +%figure(fig+1); +%close; +%figure(fig+1); + +%clf; +%movie(M,20); diff --git a/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/check_directory.m b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/check_directory.m new file mode 100755 index 0000000..dc23149 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/check_directory.m @@ -0,0 +1,97 @@ +% This small script looks in the direcory and checks if the images are there. +% +% This works only on Matlab 5.x (otherwise, the dir commands works differently) + +% (c) Jean-Yves Bouguet - Dec. 27th, 1999 + +l = dir([calib_name '*']); + +Nl = size(l,1); +Nima_valid = 0; +ind_valid = []; +loc_extension = []; +length_name = size(calib_name,2); + +if Nl > 0, + + for pp = 1:Nl, + filenamepp = l(pp).name; + iii = findstr(filenamepp,calib_name); + + loc_ext = findstr(filenamepp,format_image); + string_num = filenamepp(length_name+1:loc_ext - 2); + + if isempty(str2num(string_num)), + iii = []; + end; + + + if ~isempty(iii), + if (iii(1) ~= 1), + iii = []; + end; + end; + + + + if ~isempty(iii) & ~isempty(loc_ext), + + Nima_valid = Nima_valid + 1; + ind_valid = [ind_valid pp]; + loc_extension = [loc_extension loc_ext(1)]; + + end; + + end; + + if (Nima_valid==0), + + fprintf(1,'No image found. File format may be wrong.\n'); + + else + + % Get all the string numbers: + + string_length = zeros(1,Nima_valid); + indices = zeros(1,Nima_valid); + + + for ppp = 1:Nima_valid, + + name = l(ind_valid(ppp)).name; + string_num = name(length_name+1:loc_extension(ppp) - 2); + string_length(ppp) = size(string_num,2); + indices(ppp) = str2num(string_num); + + end; + + % Number of images... + first_num = min(indices); + n_ima = max(indices) - first_num + 1; + + if min(string_length) == max(string_length), + + N_slots = min(string_length); + type_numbering = 1; + + else + + N_slots = 1; + type_numbering = 0; + + end; + + image_numbers = first_num:n_ima-1+first_num; + + %%% By default, all the images are active for calibration: + + active_images = ones(1,n_ima); + + end; + +else + + fprintf(1,'No image found. Basename may be wrong.\n'); + +end; + diff --git a/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/check_extracted_images.m b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/check_extracted_images.m new file mode 100755 index 0000000..fa7df87 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/check_extracted_images.m @@ -0,0 +1,37 @@ +check_active_images; + +for kk = ind_active, + + if ~exist(['x_' num2str(kk)]), + + fprintf(1,'WARNING: Need to extract grid corners on image %d\n',kk); + + active_images(kk) = 0; + + eval(['dX_' num2str(kk) ' = NaN;']); + eval(['dY_' num2str(kk) ' = NaN;']); + + eval(['wintx_' num2str(kk) ' = NaN;']); + eval(['winty_' num2str(kk) ' = NaN;']); + + eval(['x_' num2str(kk) ' = NaN*ones(2,1);']); + eval(['X_' num2str(kk) ' = NaN*ones(3,1);']); + + eval(['n_sq_x_' num2str(kk) ' = NaN;']); + eval(['n_sq_y_' num2str(kk) ' = NaN;']); + + else + + eval(['xkk = x_' num2str(kk) ';']); + + if isnan(xkk(1)), + + fprintf(1,'WARNING: Need to extract grid corners on image %d - This image is now set inactive\n',kk); + + active_images(kk) = 0; + + end; + + end; + +end; diff --git a/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/clear_windows.m b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/clear_windows.m new file mode 100755 index 0000000..1eccbd3 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/clear_windows.m @@ -0,0 +1,4 @@ +for kk = 1:n_ima, + eval(['clear wintx_' num2str(kk)]); + eval(['clear winty_' num2str(kk)]); +end; diff --git a/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/clearwin.m b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/clearwin.m new file mode 100755 index 0000000..a04be67 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/clearwin.m @@ -0,0 +1,10 @@ +% Function that clears all the wintx_i and winty_i +% In normal operation of the toolbox, this function should not be +% useful. +% only in cases where you want to re-extract corners using the Extract grid corners another time... not common. You might as well use the Recomp. corners. + +for kk = 1:n_ima, + + eval(['clear wintx_' num2str(kk) ' winty_' num2str(kk)]); + +end; diff --git a/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/click_calib.m b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/click_calib.m new file mode 100755 index 0000000..1a6d2d7 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/click_calib.m @@ -0,0 +1,193 @@ +%if exist('images_read'); +% active_images = active_images & images_read; +%end; + +var2fix = 'dX_default'; + +fixvariable; + +var2fix = 'dY_default'; + +fixvariable; + +var2fix = 'map'; + +fixvariable; + + +if ~exist('n_ima'), + data_calib; +end; + +check_active_images; + +if ~exist(['I_' num2str(ind_active(1))]), + ima_read_calib; + if isempty(ind_read), + disp('Cannot extract corners without images'); + return; + end; +end; + + +%wintx = 10; % neigborhood of integration for +%winty = 10; % the corner finder + +fprintf(1,'\nExtraction of the grid corners on the images\n'); + + +if ~exist('map'), map = gray(256); end; + + +disp('WARNING!!! Do not forget to change dX_default and dY_default in click_calib.m!!!') + +if ~exist('dX_default'); + +% Default size of the pattern squares; + +% Setup of JY (old at Caltech) +%dX_default = 21.9250/11; +%dY_default = 18.1250/9; + +% Setup of JY (new at Intel) +%dX_default = 1.9750; +%dY_default = 1.9865; + + +% Setup of Luis and Enrico +%dX_default = 67.7/16; +%dY_default = 50.65/12; + + +% Setup of German +%dX_default = 10.16; +%dY_default = 10.16; + +% Setup of JY (new at Intel) +%dX_default = 1.9750*2.54; +%dY_default = 1.9865*2.54; + +% Setup of JY - 3D calibration rig at Intel (new at Intel) +%dX_default = 3; +%dY_default = 3; + +% Setup of JY - 3D calibration rig at Intel (new at Intel) - use units in mm to match Zhang +dX_default = 30; +dY_default = 30; + +end; + + +if ~exist('dont_ask'), + dont_ask = 0; +end; + + +if ~dont_ask, + ima_numbers = input('Number(s) of image(s) to process ([] = all images) = '); +else + ima_numbers = []; +end; + +if isempty(ima_numbers), + ima_proc = 1:n_ima; +else + ima_proc = ima_numbers; +end; + + +% Useful option to add images: +kk_first = ima_proc(1); %input('Start image number ([]=1=first): '); + +%if isempty(kk_first), kk_first = 1; end; + + +if exist(['wintx_' num2str(kk_first)]), + + eval(['wintxkk = wintx_' num2str(kk_first) ';']); + + if isempty(wintxkk) | isnan(wintxkk), + + disp('Window size for corner finder (wintx and winty):'); + wintx = input('wintx ([] = 5) = '); + if isempty(wintx), wintx = 5; end; + wintx = round(wintx); + winty = input('winty ([] = 5) = '); + if isempty(winty), winty = 5; end; + winty = round(winty); + + fprintf(1,'Window size = %dx%d\n',2*wintx+1,2*winty+1); + + end; + +else + + disp('Window size for corner finder (wintx and winty):'); + wintx = input('wintx ([] = 5) = '); + if isempty(wintx), wintx = 5; end; + wintx = round(wintx); + winty = input('winty ([] = 5) = '); + if isempty(winty), winty = 5; end; + winty = round(winty); + + fprintf(1,'Window size = %dx%d\n',2*wintx+1,2*winty+1); + +end; + + +for kk = ima_proc, + if exist(['I_' num2str(kk)]), + click_ima_calib; + active_images(kk) = 1; + else + eval(['dX_' num2str(kk) ' = NaN;']); + eval(['dY_' num2str(kk) ' = NaN;']); + + eval(['wintx_' num2str(kk) ' = NaN;']); + eval(['winty_' num2str(kk) ' = NaN;']); + + eval(['x_' num2str(kk) ' = NaN*ones(2,1);']); + eval(['X_' num2str(kk) ' = NaN*ones(3,1);']); + + eval(['n_sq_x_' num2str(kk) ' = NaN;']); + eval(['n_sq_y_' num2str(kk) ' = NaN;']); + end; +end; + + +check_active_images; + + +% Fix potential non-existing variables: + +for kk = 1:n_ima, + if ~exist(['x_' num2str(kk)]), + eval(['dX_' num2str(kk) ' = NaN;']); + eval(['dY_' num2str(kk) ' = NaN;']); + + eval(['wintx_' num2str(kk) ' = NaN;']); + eval(['winty_' num2str(kk) ' = NaN;']); + + eval(['x_' num2str(kk) ' = NaN*ones(2,1);']); + eval(['X_' num2str(kk) ' = NaN*ones(3,1);']); + + eval(['n_sq_x_' num2str(kk) ' = NaN;']); + eval(['n_sq_y_' num2str(kk) ' = NaN;']); + end; +end; + + +string_save = 'save calib_data active_images ind_active wintx winty n_ima type_numbering N_slots first_num image_numbers format_image calib_name Hcal Wcal nx ny map dX_default dY_default dX dY'; + +for kk = 1:n_ima, + string_save = [string_save ' X_' num2str(kk) ' x_' num2str(kk) ' n_sq_x_' num2str(kk) ' n_sq_y_' num2str(kk) ' wintx_' num2str(kk) ' winty_' num2str(kk) ' dX_' num2str(kk) ' dY_' num2str(kk)]; +end; + +eval(string_save); + +disp('done'); + +return; + +go_calib_optim; + diff --git a/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/click_ima_calib.m b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/click_ima_calib.m new file mode 100755 index 0000000..f0fd4ca --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/click_ima_calib.m @@ -0,0 +1,230 @@ + % Cleaned-up version of init_calib.m + + fprintf(1,'\nProcessing image %d...\n',kk); + + eval(['I = I_' num2str(kk) ';']); + + if exist(['wintx_' num2str(kk)]), + + eval(['wintxkk = wintx_' num2str(kk) ';']); + + if ~isempty(wintxkk) & ~isnan(wintxkk), + + eval(['wintx = wintx_' num2str(kk) ';']); + eval(['winty = winty_' num2str(kk) ';']); + + end; + end; + + + fprintf(1,'Using (wintx,winty)=(%d,%d) - Window size = %dx%d\n',wintx,winty,2*wintx+1,2*winty+1); + + + figure(2); + image(I); + colormap(map); + + title(['Click on the four extreme corners of the rectangular pattern... Image ' num2str(kk)]); + + disp('Click on the four extreme corners of the rectangular complete pattern...'); + + [x,y] = ginput3(4); + + [Xc,good,bad,type] = cornerfinder([x';y'],I,winty,wintx); % the four corners + + x = Xc(1,:)'; + y = Xc(2,:)'; + + [y,indy] = sort(y); + x = x(indy); + + if (x(2) > x(1)), + x4 = x(1);y4 = y(1); x3 = x(2); y3 = y(2); + else + x4 = x(2);y4 = y(2); x3 = x(1); y3 = y(1); + end; + if (x(3) > x(4)), + x2 = x(3);y2 = y(3); x1 = x(4); y1 = y(4); + else + x2 = x(4);y2 = y(4); x1 = x(3); y1 = y(3); + end; + + x = [x1;x2;x3;x4]; + y = [y1;y2;y3;y4]; + + + figure(2); hold on; + plot([x;x(1)],[y;y(1)],'g-'); + plot(x,y,'og'); + hx=text((x(4)+x(3))/2,(y(4)+y(3))/2 - 20,'X'); + set(hx,'color','g','Fontsize',14); + hy=text((x(4)+x(1))/2-20,(y(4)+y(1))/2,'Y'); + set(hy,'color','g','Fontsize',14); + hold off; + + + % Try to automatically count the number of squares in the grid + + n_sq_x1 = count_squares(I,x1,y1,x2,y2,wintx); + n_sq_x2 = count_squares(I,x3,y3,x4,y4,wintx); + n_sq_y1 = count_squares(I,x2,y2,x3,y3,wintx); + n_sq_y2 = count_squares(I,x4,y4,x1,y1,wintx); + + + + % If could not count the number of squares, enter manually + + if (n_sq_x1~=n_sq_x2)|(n_sq_y1~=n_sq_y2), + + + disp('Could not count the number of squares in the grid. Enter manually.'); + n_sq_x = input('Number of squares along the X direction ([]=10) = '); %6 + if isempty(n_sq_x), n_sq_x = 10; end; + n_sq_y = input('Number of squares along the Y direction ([]=10) = '); %6 + if isempty(n_sq_y), n_sq_y = 10; end; + + else + + n_sq_x = n_sq_x1; + n_sq_y = n_sq_y1; + + end; + + + % Enter the size of each square + + dX = input(['Size dX of each square along the X direction ([]=' num2str(dX_default) 'mm) = ']); + dY = input(['Size dY of each square along the Y direction ([]=' num2str(dY_default) 'mm) = ']); + if isempty(dX), dX = dX_default; else dX_default = dX; end; + if isempty(dY), dY = dY_default; else dY_default = dY; end; + + % Compute the inside points through computation of the planar homography (collineation) + + a00 = [x(1);y(1);1]; + a10 = [x(2);y(2);1]; + a11 = [x(3);y(3);1]; + a01 = [x(4);y(4);1]; + + + % Compute the planar collineation: (return the normalization matrix as well) + + [Homo,Hnorm,inv_Hnorm] = compute_homography ([a00 a10 a11 a01],[0 1 1 0;0 0 1 1;1 1 1 1]); + + + % Build the grid using the planar collineation: + + x_l = ((0:n_sq_x)'*ones(1,n_sq_y+1))/n_sq_x; + y_l = (ones(n_sq_x+1,1)*(0:n_sq_y))/n_sq_y; + pts = [x_l(:) y_l(:) ones((n_sq_x+1)*(n_sq_y+1),1)]'; + + XX = Homo*pts; + XX = XX(1:2,:) ./ (ones(2,1)*XX(3,:)); + + + % Complete size of the rectangle + + W = n_sq_x*dX; + L = n_sq_y*dY; + + + + + %%%%%%%%%%%%%%%%%%%%%%%% ADDITIONAL STUFF IN THE CASE OF HIGHLY DISTORTED IMAGES %%%%%%%%%%%%% + figure(2); + hold on; + plot(XX(1,:),XX(2,:),'r+'); + title('The red crosses should be close to the image corners'); + hold off; + + disp('If the guessed grid corners (red crosses on the image) are not close to the actual corners,'); + disp('it is necessary to enter an initial guess for the radial distortion factor kc (useful for subpixel detection)'); + quest_distort = input('Need of an initial guess for distortion? ([]=no, other=yes) '); + + quest_distort = ~isempty(quest_distort); + + if quest_distort, + % Estimation of focal length: + c_g = [size(I,2);size(I,1)]/2 + .5; + f_g = Distor2Calib(0,[[x(1) x(2) x(4) x(3)] - c_g(1);[y(1) y(2) y(4) y(3)] - c_g(2)],1,1,4,W,L,[-W/2 W/2 W/2 -W/2;L/2 L/2 -L/2 -L/2; 0 0 0 0],100,1,1); + f_g = mean(f_g); + script_fit_distortion; + end; + %%%%%%%%%%%%%%%%%%%%% END ADDITIONAL STUFF IN THE CASE OF HIGHLY DISTORTED IMAGES %%%%%%%%%%%%% + + + + + + Np = (n_sq_x+1)*(n_sq_y+1); + + disp('Corner extraction...'); + + grid_pts = cornerfinder(XX,I,winty,wintx); %%% Finds the exact corners at every points! + + + + %save all_corners x y grid_pts + + grid_pts = grid_pts - 1; % subtract 1 to bring the origin to (0,0) instead of (1,1) in matlab (not necessary in C) + + + + ind_corners = [1 n_sq_x+1 (n_sq_x+1)*n_sq_y+1 (n_sq_x+1)*(n_sq_y+1)]; % index of the 4 corners + ind_orig = (n_sq_x+1)*n_sq_y + 1; + xorig = grid_pts(1,ind_orig); + yorig = grid_pts(2,ind_orig); + dxpos = mean([grid_pts(:,ind_orig) grid_pts(:,ind_orig+1)]'); + dypos = mean([grid_pts(:,ind_orig) grid_pts(:,ind_orig-n_sq_x-1)]'); + + + x_box_kk = [grid_pts(1,:)-(wintx+.5);grid_pts(1,:)+(wintx+.5);grid_pts(1,:)+(wintx+.5);grid_pts(1,:)-(wintx+.5);grid_pts(1,:)-(wintx+.5)]; + y_box_kk = [grid_pts(2,:)-(winty+.5);grid_pts(2,:)-(winty+.5);grid_pts(2,:)+(winty+.5);grid_pts(2,:)+(winty+.5);grid_pts(2,:)-(winty+.5)]; + + + figure(3); + image(I); colormap(map); hold on; + plot(grid_pts(1,:)+1,grid_pts(2,:)+1,'r+'); + plot(x_box_kk+1,y_box_kk+1,'-b'); + plot(grid_pts(1,ind_corners)+1,grid_pts(2,ind_corners)+1,'mo'); + plot(xorig+1,yorig+1,'*m'); + h = text(xorig-15,yorig-15,'O'); + set(h,'Color','m','FontSize',14); + h2 = text(dxpos(1)-10,dxpos(2)-10,'dX'); + set(h2,'Color','g','FontSize',14); + h3 = text(dypos(1)-25,dypos(2)-3,'dY'); + set(h3,'Color','g','FontSize',14); + xlabel('Xc (in camera frame)'); + ylabel('Yc (in camera frame)'); + title('Extracted corners'); + zoom on; + drawnow; + hold off; + + + Xi = reshape(([0:n_sq_x]*dX)'*ones(1,n_sq_y+1),Np,1)'; + Yi = reshape(ones(n_sq_x+1,1)*[n_sq_y:-1:0]*dY,Np,1)'; + Zi = zeros(1,Np); + + Xgrid = [Xi;Yi;Zi]; + + + % All the point coordinates (on the image, and in 3D) - for global optimization: + + x = grid_pts; + X = Xgrid; + + + % Saves all the data into variables: + + eval(['dX_' num2str(kk) ' = dX;']); + eval(['dY_' num2str(kk) ' = dY;']); + + eval(['wintx_' num2str(kk) ' = wintx;']); + eval(['winty_' num2str(kk) ' = winty;']); + + eval(['x_' num2str(kk) ' = x;']); + eval(['X_' num2str(kk) ' = X;']); + + eval(['n_sq_x_' num2str(kk) ' = n_sq_x;']); + eval(['n_sq_y_' num2str(kk) ' = n_sq_y;']); + \ No newline at end of file diff --git a/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/click_ima_calib3D.m b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/click_ima_calib3D.m new file mode 100755 index 0000000..7718268 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/click_ima_calib3D.m @@ -0,0 +1,482 @@ + % Cleaned-up version of init_calib.m + + eval(['I = I_' num2str(kk) ';']); + + figure(2); + image(I); + colormap(map); + + + + + + %%%%%%%%%%%%%%%%%%%%%%%%% LEFT PATTERN ACQUISITION %%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + + + title(['Click on the four extreme corners of the left rectangular pattern... Image ' num2str(kk)]); + + disp('Click on the four extreme corners of the left rectangular pattern...'); + + [x,y] = ginput3(4); + + [Xc,good,bad,type] = cornerfinder([x';y'],I,winty,wintx); % the four corners + + x = Xc(1,:)'; + y = Xc(2,:)'; + + [y,indy] = sort(y); + x = x(indy); + + if (x(2) > x(1)), + x4 = x(1);y4 = y(1); x3 = x(2); y3 = y(2); + else + x4 = x(2);y4 = y(2); x3 = x(1); y3 = y(1); + end; + if (x(3) > x(4)), + x2 = x(3);y2 = y(3); x1 = x(4); y1 = y(4); + else + x2 = x(4);y2 = y(4); x1 = x(3); y1 = y(3); + end; + + x = [x1;x2;x3;x4]; + y = [y1;y2;y3;y4]; + + + figure(2); hold on; + plot([x;x(1)],[y;y(1)],'g-'); + plot(x,y,'og'); + hx=text((x(4)+x(3))/2,(y(4)+y(3))/2 - 20,'X'); + set(hx,'color','g','Fontsize',14); + hy=text((x(4)+x(1))/2-20,(y(4)+y(1))/2,'Y'); + set(hy,'color','g','Fontsize',14); + hold off; + + drawnow; + + + % Try to automatically count the number of squares in the grid + + n_sq_x1 = count_squares(I,x1,y1,x2,y2,wintx); + n_sq_x2 = count_squares(I,x3,y3,x4,y4,wintx); + n_sq_y1 = count_squares(I,x2,y2,x3,y3,wintx); + n_sq_y2 = count_squares(I,x4,y4,x1,y1,wintx); + + + + % If could not count the number of squares, enter manually + + if (n_sq_x1~=n_sq_x2)|(n_sq_y1~=n_sq_y2), + + + disp('Could not count the number of squares in the grid. Enter manually.'); + n_sq_x = input('Number of squares along the X direction ([]=10) = '); %6 + if isempty(n_sq_x), n_sq_x = 10; end; + n_sq_y = input('Number of squares along the Y direction ([]=10) = '); %6 + if isempty(n_sq_y), n_sq_y = 10; end; + + else + + n_sq_x = n_sq_x1; + n_sq_y = n_sq_y1; + + end; + + + if 1, + % Enter the size of each square + + dX = input(['Size dX of each square along the X direction ([]=' num2str(dX_default) 'cm) = ']); + dY = input(['Size dY of each square along the Y direction ([]=' num2str(dY_default) 'cm) = ']); + if isempty(dX), dX = dX_default; else dX_default = dX; end; + if isempty(dY), dY = dY_default; else dY_default = dY; end; + + else + + dX = 3; + dY = 3; + + end; + + + % Compute the inside points through computation of the planar homography (collineation) + + a00 = [x(1);y(1);1]; + a10 = [x(2);y(2);1]; + a11 = [x(3);y(3);1]; + a01 = [x(4);y(4);1]; + + + % Compute the planart collineation: (return the normalization matrice as well) + + [Homo,Hnorm,inv_Hnorm] = compute_collineation (a00, a10, a11, a01); + + + % Build the grid using the planar collineation: + + x_l = ((0:n_sq_x)'*ones(1,n_sq_y+1))/n_sq_x; + y_l = (ones(n_sq_x+1,1)*(0:n_sq_y))/n_sq_y; + pts = [x_l(:) y_l(:) ones((n_sq_x+1)*(n_sq_y+1),1)]'; + + XX = Homo*pts; + XX = XX(1:2,:) ./ (ones(2,1)*XX(3,:)); + + + % Complete size of the rectangle + + W = n_sq_x*dX; + L = n_sq_y*dY; + + + + if 1, + %%%%%%%%%%%%%%%%%%%%%%%% ADDITIONAL STUFF IN THE CASE OF HIGHLY DISTORTED IMAGES %%%%%%%%%%%%% + figure(2); + hold on; + plot(XX(1,:),XX(2,:),'r+'); + title('The red crosses should be close to the image corners'); + hold off; + + disp('If the guessed grid corners (red crosses on the image) are not close to the actual corners,'); + disp('it is necessary to enter an initial guess for the radial distortion factor kc (useful for subpixel detection)'); + quest_distort = input('Need of an initial guess for distortion? ([]=no, other=yes) '); + + quest_distort = ~isempty(quest_distort); + + if quest_distort, + % Estimation of focal length: + c_g = [size(I,2);size(I,1)]/2 + .5; + f_g = Distor2Calib(0,[[x(1) x(2) x(4) x(3)] - c_g(1);[y(1) y(2) y(4) y(3)] - c_g(2)],1,1,4,W,L,[-W/2 W/2 W/2 -W/2;L/2 L/2 -L/2 -L/2; 0 0 0 0],100,1,1); + f_g = mean(f_g); + script_fit_distortion; + end; + %%%%%%%%%%%%%%%%%%%%% END ADDITIONAL STUFF IN THE CASE OF HIGHLY DISTORTED IMAGES %%%%%%%%%%%%% + end; + + + Np = (n_sq_x+1)*(n_sq_y+1); + + disp('Corner extraction...'); + + grid_pts = cornerfinder(XX,I,winty,wintx); %%% Finds the exact corners at every points! + + %save all_corners x y grid_pts + + grid_pts = grid_pts - 1; % subtract 1 to bring the origin to (0,0) instead of (1,1) in matlab (not necessary in C) + + + % Global Homography from plane to pixel coordinates: + + H_total = [1 0 -1 ; 0 1 -1 ; 0 0 1]*Homo*[1 0 0;0 -1 1;0 0 1]*[1/W 0 0 ; 0 1/L 0; 0 0 1]; + % WARNING!!! the first matrix (on the left side) takes care of the transformation of the pixel cooredinates by -1 (previous line) + % If it is not done, then this matrix should not appear (in C) + H_total = H_total / H_total(3,3); + + + ind_corners = [1 n_sq_x+1 (n_sq_x+1)*n_sq_y+1 (n_sq_x+1)*(n_sq_y+1)]; % index of the 4 corners + ind_orig = (n_sq_x+1)*n_sq_y + 1; + xorig = grid_pts(1,ind_orig); + yorig = grid_pts(2,ind_orig); + dxpos = mean([grid_pts(:,ind_orig) grid_pts(:,ind_orig+1)]'); + dypos = mean([grid_pts(:,ind_orig) grid_pts(:,ind_orig-n_sq_x-1)]'); + + + x_box_kk = [grid_pts(1,:)-(wintx+.5);grid_pts(1,:)+(wintx+.5);grid_pts(1,:)+(wintx+.5);grid_pts(1,:)-(wintx+.5);grid_pts(1,:)-(wintx+.5)]; + y_box_kk = [grid_pts(2,:)-(winty+.5);grid_pts(2,:)-(winty+.5);grid_pts(2,:)+(winty+.5);grid_pts(2,:)+(winty+.5);grid_pts(2,:)-(winty+.5)]; + + + figure(3); + image(I); colormap(map); hold on; + plot(grid_pts(1,:)+1,grid_pts(2,:)+1,'r+'); + plot(x_box_kk+1,y_box_kk+1,'-b'); + plot(grid_pts(1,ind_corners)+1,grid_pts(2,ind_corners)+1,'mo'); + plot(xorig+1,yorig+1,'*m'); + h = text(xorig-15,yorig-15,'O'); + set(h,'Color','m','FontSize',14); + h2 = text(dxpos(1)-10,dxpos(2)-10,'dX'); + set(h2,'Color','g','FontSize',14); + h3 = text(dypos(1)-25,dypos(2)-3,'dY'); + set(h3,'Color','g','FontSize',14); + xlabel('Xc (in camera frame)'); + ylabel('Yc (in camera frame)'); + title('Extracted corners'); + zoom on; + drawnow; + hold off; + + + Xi = reshape(([0:n_sq_x]*dX)'*ones(1,n_sq_y+1),Np,1)'; + Yi = reshape(ones(n_sq_x+1,1)*[n_sq_y:-1:0]*dY,Np,1)'; + Zi = zeros(1,Np); + + Xgrid = [Xi;Yi;Zi]; + + + % All the point coordinates (on the image, and in 3D) - for global optimization: + + x = grid_pts; + X = Xgrid; + + + % The left pannel info: + + xl = x; + Xl = X; + nl_sq_x = n_sq_x; + nl_sq_y = n_sq_y; + Hl = H_total; + + + + + + + %%%%%%%%%%%%%%%%%%%%%%%%% RIGHT PATTERN ACQUISITION %%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + + x1 = a10(1)/a10(3); + x4 = a11(1)/a11(3); + + y1 = a10(2)/a10(3); + y4 = a11(2)/a11(3); + + + figure(2); + hold on; + plot([x1 x4],[y1 y4],'c-'); + plot([x1 x4],[y1 y4],'co'); + hold off; + + title(['Click on the two remaining extreme corners of the right rectangular pattern... Image ' num2str(kk)]); + + disp('Click on the two remaining extreme corners of the right rectangular pattern...'); + + [x,y] = ginput3(2); + + [Xc,good,bad,type] = cornerfinder([x';y'],I,winty,wintx); % the four corners + + x = Xc(1,:)'; + y = Xc(2,:)'; + + [y,indy] = sort(y); + x = x(indy); + + x2 = x(2); + x3 = x(1); + + y2 = y(2); + y3 = y(1); + + + x = [x1;x2;x3;x4]; + y = [y1;y2;y3;y4]; + + figure(2); hold on; + plot([x;x(1)],[y;y(1)],'c-'); + plot(x,y,'oc'); + hx=text((x(4)+x(3))/2,(y(4)+y(3))/2 - 20,'X'); + set(hx,'color','c','Fontsize',14); + hy=text((x(4)+x(1))/2-20,(y(4)+y(1))/2,'Y'); + set(hy,'color','c','Fontsize',14); + hold off; + drawnow; + + + % Try to automatically count the number of squares in the grid + + n_sq_x1 = count_squares(I,x1,y1,x2,y2,wintx); + n_sq_x2 = count_squares(I,x3,y3,x4,y4,wintx); + n_sq_y1 = count_squares(I,x2,y2,x3,y3,wintx); + n_sq_y2 = count_squares(I,x4,y4,x1,y1,wintx); + + + + % If could not count the number of squares, enter manually + + if (n_sq_x1~=n_sq_x2)|(n_sq_y1~=n_sq_y2), + + + disp('Could not count the number of squares in the grid. Enter manually.'); + n_sq_x = input('Number of squares along the X direction ([]=10) = '); %6 + if isempty(n_sq_x), n_sq_x = 10; end; + n_sq_y = input('Number of squares along the Y direction ([]=10) = '); %6 + if isempty(n_sq_y), n_sq_y = 10; end; + + else + + n_sq_x = n_sq_x1; + n_sq_y = n_sq_y1; + + end; + + + if 1, + % Enter the size of each square + + dX = input(['Size dX of each square along the X direction ([]=' num2str(dX_default) 'cm) = ']); + dY = input(['Size dY of each square along the Y direction ([]=' num2str(dY_default) 'cm) = ']); + if isempty(dX), dX = dX_default; else dX_default = dX; end; + if isempty(dY), dY = dY_default; else dY_default = dY; end; + + else + + dX = 3; + dY = 3; + + end; + + + % Compute the inside points through computation of the planar homography (collineation) + + a00 = [x(1);y(1);1]; + a10 = [x(2);y(2);1]; + a11 = [x(3);y(3);1]; + a01 = [x(4);y(4);1]; + + + % Compute the planart collineation: (return the normalization matrice as well) + + [Homo,Hnorm,inv_Hnorm] = compute_collineation (a00, a10, a11, a01); + + + % Build the grid using the planar collineation: + + x_l = ((0:n_sq_x)'*ones(1,n_sq_y+1))/n_sq_x; + y_l = (ones(n_sq_x+1,1)*(0:n_sq_y))/n_sq_y; + pts = [x_l(:) y_l(:) ones((n_sq_x+1)*(n_sq_y+1),1)]'; + + XX = Homo*pts; + XX = XX(1:2,:) ./ (ones(2,1)*XX(3,:)); + + + % Complete size of the rectangle + + W = n_sq_x*dX; + L = n_sq_y*dY; + + + + if 1, + %%%%%%%%%%%%%%%%%%%%%%%% ADDITIONAL STUFF IN THE CASE OF HIGHLY DISTORTED IMAGES %%%%%%%%%%%%% + figure(2); + hold on; + plot(XX(1,:),XX(2,:),'r+'); + title('The red crosses should be close to the image corners'); + hold off; + + disp('If the guessed grid corners (red crosses on the image) are not close to the actual corners,'); + disp('it is necessary to enter an initial guess for the radial distortion factor kc (useful for subpixel detection)'); + quest_distort = input('Need of an initial guess for distortion? ([]=no, other=yes) '); + + quest_distort = ~isempty(quest_distort); + + if quest_distort, + % Estimation of focal length: + c_g = [size(I,2);size(I,1)]/2 + .5; + f_g = Distor2Calib(0,[[x(1) x(2) x(4) x(3)] - c_g(1);[y(1) y(2) y(4) y(3)] - c_g(2)],1,1,4,W,L,[-W/2 W/2 W/2 -W/2;L/2 L/2 -L/2 -L/2; 0 0 0 0],100,1,1); + f_g = mean(f_g); + script_fit_distortion; + end; + %%%%%%%%%%%%%%%%%%%%% END ADDITIONAL STUFF IN THE CASE OF HIGHLY DISTORTED IMAGES %%%%%%%%%%%%% + end; + + + Np = (n_sq_x+1)*(n_sq_y+1); + + disp('Corner extraction...'); + + grid_pts = cornerfinder(XX,I,winty,wintx); %%% Finds the exact corners at every points! + + %save all_corners x y grid_pts + + grid_pts = grid_pts - 1; % subtract 1 to bring the origin to (0,0) instead of (1,1) in matlab (not necessary in C) + + + % Global Homography from plane to pixel coordinates: + + H_total = [1 0 -1 ; 0 1 -1 ; 0 0 1]*Homo*[1 0 0;0 -1 1;0 0 1]*[1/W 0 0 ; 0 1/L 0; 0 0 1]; + % WARNING!!! the first matrix (on the left side) takes care of the transformation of the pixel cooredinates by -1 (previous line) + % If it is not done, then this matrix should not appear (in C) + H_total = H_total / H_total(3,3); + + + ind_corners = [1 n_sq_x+1 (n_sq_x+1)*n_sq_y+1 (n_sq_x+1)*(n_sq_y+1)]; % index of the 4 corners + ind_orig = (n_sq_x+1)*n_sq_y + 1; + xorig = grid_pts(1,ind_orig); + yorig = grid_pts(2,ind_orig); + dxpos = mean([grid_pts(:,ind_orig) grid_pts(:,ind_orig+1)]'); + dypos = mean([grid_pts(:,ind_orig) grid_pts(:,ind_orig-n_sq_x-1)]'); + + + x_box_kk = [grid_pts(1,:)-(wintx+.5);grid_pts(1,:)+(wintx+.5);grid_pts(1,:)+(wintx+.5);grid_pts(1,:)-(wintx+.5);grid_pts(1,:)-(wintx+.5)]; + y_box_kk = [grid_pts(2,:)-(winty+.5);grid_pts(2,:)-(winty+.5);grid_pts(2,:)+(winty+.5);grid_pts(2,:)+(winty+.5);grid_pts(2,:)-(winty+.5)]; + + + figure(3); + hold on; + plot(grid_pts(1,:)+1,grid_pts(2,:)+1,'r+'); + plot(x_box_kk+1,y_box_kk+1,'-b'); + plot(grid_pts(1,ind_corners)+1,grid_pts(2,ind_corners)+1,'mo'); + plot(xorig+1,yorig+1,'*m'); + h = text(xorig-15,yorig-15,'O'); + set(h,'Color','m','FontSize',14); + h2 = text(dxpos(1)-10,dxpos(2)-10,'dX'); + set(h2,'Color','g','FontSize',14); + h3 = text(dypos(1)-25,dypos(2)-3,'dY'); + set(h3,'Color','g','FontSize',14); + xlabel('Xc (in camera frame)'); + ylabel('Yc (in camera frame)'); + title('Extracted corners'); + zoom on; + drawnow; + hold off; + + + Xi = reshape(([0:n_sq_x]*dX)'*ones(1,n_sq_y+1),Np,1)'; + Yi = reshape(ones(n_sq_x+1,1)*[n_sq_y:-1:0]*dY,Np,1)'; + Zi = zeros(1,Np); + + Xgrid = [Xi;Yi;Zi]; + + + % All the point coordinates (on the image, and in 3D) - for global optimization: + + x = grid_pts; + X = Xgrid; + + + % The right pannel info: + + xr = x; + Xr = X; + nr_sq_x = n_sq_x; + nr_sq_y = n_sq_y; + Hr = H_total; + + + +%%%%%%%% REGROUP THE LEFT AND RIHT PATTERNS %%%%%%%%%%%%% + + +Xr2 = [0 0 1;0 1 0;-1 0 0]*Xr + [dX*nl_sq_x;0;0]*ones(1,length(Xr)); + + +x = [xl xr]; + +X = [Xl Xr2]; + + + + eval(['x_' num2str(kk) ' = x;']); + eval(['X_' num2str(kk) ' = X;']); + + eval(['nl_sq_x_' num2str(kk) ' = nl_sq_x;']); + eval(['nl_sq_y_' num2str(kk) ' = nl_sq_y;']); + + eval(['nr_sq_x_' num2str(kk) ' = nr_sq_x;']); + eval(['nr_sq_y_' num2str(kk) ' = nr_sq_y;']); + + % Save the global planar homography: + + eval(['Hl_' num2str(kk) ' = Hl;']); + eval(['Hr_' num2str(kk) ' = Hr;']); \ No newline at end of file diff --git a/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/comp_distortion.m b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/comp_distortion.m new file mode 100755 index 0000000..a0f03de --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/comp_distortion.m @@ -0,0 +1,38 @@ +function [x_comp] = comp_distortion(x_dist,k2); + +% [x_comp] = comp_distortion(x_dist,k2); +% +% compensates the radial distortion of the camera +% on the image plane. +% +% x_dist : the image points got without considering the +% radial distortion. +% x : The image plane points after correction for the distortion +% +% x and x_dist are 2xN arrays +% +% NOTE : This compensation has to be done after the substraction +% of the center of projection, and division by the focal +% length. +% +% (do it up to a second order approximation) + +[two,N] = size(x_dist); + +if (two ~= 2 ), + error('ERROR : The dimension of the points should be 2xN'); +end; + +if length(k2) > 2, + [x_comp] = comp_distortion_oulu(x_dist,k2); +else + +radius_2= x_dist(1,:).^2 + x_dist(2,:).^2; +radial_distortion = 1 + ones(2,1)*(k2 * radius_2); +radius_2_comp = (x_dist(1,:).^2 + x_dist(2,:).^2) ./ radial_distortion(1,:); +radial_distortion = 1 + ones(2,1)*(k2 * radius_2_comp); +x_comp = x_dist ./ radial_distortion; + +end; + +%% Function completely checked : It works fine !!! \ No newline at end of file diff --git a/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/comp_distortion2.m b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/comp_distortion2.m new file mode 100755 index 0000000..532ee9a --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/comp_distortion2.m @@ -0,0 +1,71 @@ +function [x_comp] = comp_distortion(x_dist,k2); + +% [x_comp] = comp_distortion(x_dist,k2); +% +% compensates the radial distortion of the camera +% on the image plane. +% +% x_dist : the image points got without considering the +% radial distortion. +% k2: Radial distortion factor +% +% x : The image plane points after correction for the distortion +% +% x and x_dist are 2xN arrays +% +% NOTE : This compensation has to be done after the substraction +% of the center of projection, and division by the focal +% length. +% +% Solve for cubic roots using method from Numerical Recipes in C 2nd Ed. +% pages 184-185. + + +% California Institute of Technology +% (c) Jean-Yves Bouguet - April 27th, 1998 + +% fully checked! JYB, april 27th, 1998 - 2am + +if k2 ~= 0, + +[two,N] = size(x_dist); + +if (two ~= 2 ), + error('ERROR : The dimension of the points should be 2xN'); +end; + + +ph = atan2(x_dist(2,:),x_dist(1,:)); + +Q = -1/(3*k2); +R = -x_dist(1,:)./(2*k2*cos(ph)); + +R2 = R.^2; +Q3 = Q^3; + + +if k2 < 0, + + % this works in all practical situations (it starts failing for very large + % values of k2) + + th = acos(R./sqrt(Q3)); + r = -2*sqrt(Q)*cos((th-2*pi)/3); + +else + + % note: this always works, even for ridiculous values of k2 + + A = (sqrt(R2-Q3)-R).^(1/3); + B = Q*(1./A); + r = (A+B); + +end; + +x_comp = [r.*cos(ph); r.*sin(ph)]; + +else + + x_comp = x_dist; + +end; diff --git a/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/comp_distortion_oulu.m b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/comp_distortion_oulu.m new file mode 100755 index 0000000..67d02d5 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/comp_distortion_oulu.m @@ -0,0 +1,47 @@ +function [x] = comp_distortion_oulu(xd,k); + +%comp_distortion_oulu.m +% +%[x] = comp_distortion_oulu(xd,k) +% +%Compensates for radial and tangential distortion. Model From Oulu university. +%For more informatino about the distortion model, check the forward projection mapping function: +%project_points.m +% +%INPUT: xd: distorted (normalized) point coordinates in the image plane (2xN matrix) +% k: Distortion coefficients (radial and tangential) (4x1 vector) +% +%OUTPUT: x: undistorted (normalized) point coordinates in the image plane (2xN matrix) +% +%Method: Iterative method for compensation. +% +%NOTE: This compensation has to be done after the subtraction +% of the principal point, and division by the focal length. + + +if length(k) < 4, + + [x] = comp_distortion(xd,k); + +else + + + k1 = k(1); + k2 = k(2); + p1 = k(3); + p2 = k(4); + + x = xd; % initial guess + + for kk=1:5; + + r_2 = sum(x.^2); + k_radial = 1 + k1 * r_2 + k2 * r_2.^2; + delta_x = [2*p1*x(1,:).*x(2,:) + p2*(r_2 + 2*x(1,:).^2) ; + p1 * (r_2 + 2*x(2,:).^2)+2*p2*x(1,:).*x(2,:)]; + x = (xd - delta_x)./(ones(2,1)*k_radial); + + end; + +end; + diff --git a/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/comp_error_calib.m b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/comp_error_calib.m new file mode 100755 index 0000000..c7bf662 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/comp_error_calib.m @@ -0,0 +1,46 @@ +%%%%%%%%%%%%%%%%%%%% RECOMPUTES THE REPROJECTION ERROR %%%%%%%%%%%%%%%%%%%%%%%% + +check_active_images; + +% Reproject the patterns on the images, and compute the pixel errors: + +ex = []; % Global error vector +x = []; % Detected corners on the image plane +y = []; % Reprojected points + +if ~exist('alpha_c'), + alpha_c = 0; +end; + +for kk = 1:n_ima, + + eval(['omckk = omc_' num2str(kk) ';']); + eval(['Tckk = Tc_' num2str(kk) ';']); + + if active_images(kk) & (~isnan(omckk(1,1))), + + %Rkk = rodrigues(omckk); + + eval(['y_' num2str(kk) ' = project_points2(X_' num2str(kk) ',omckk,Tckk,fc,cc,kc,alpha_c);']); + + eval(['ex_' num2str(kk) ' = x_' num2str(kk) ' -y_' num2str(kk) ';']); + + eval(['x_kk = x_' num2str(kk) ';']); + + eval(['ex = [ex ex_' num2str(kk) '];']); + eval(['x = [x x_' num2str(kk) '];']); + eval(['y = [y y_' num2str(kk) '];']); + + else + + % eval(['y_' num2str(kk) ' = NaN*ones(2,1);']); + + + % If inactivated image, the error does not make sense: + eval(['ex_' num2str(kk) ' = NaN*ones(2,1);']); + + end; + +end; + +err_std = std(ex')'; diff --git a/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/compute_collineation.m b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/compute_collineation.m new file mode 100755 index 0000000..809c309 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/compute_collineation.m @@ -0,0 +1,66 @@ +function [H,Hnorm,inv_Hnorm] = compute_collineation (a00, a10, a11, a01); + +% new formalism using homographies + +a00 = a00 / a00(3); +a10 = a10 / a10(3); +a11 = a11 / a11(3); +a01 = a01 / a01(3); + + +% Prenormalization of point coordinates (very important): +% (Affine normalization) + +ax = [a00(1);a10(1);a11(1);a01(1)]; +ay = [a00(2);a10(2);a11(2);a01(2)]; + +mxx = mean(ax); +myy = mean(ay); +ax = ax - mxx; +ay = ay - myy; + +scxx = mean(abs(ax)); +scyy = mean(abs(ay)); + + +Hnorm = [1/scxx 0 -mxx/scxx;0 1/scyy -myy/scyy;0 0 1]; +inv_Hnorm = [scxx 0 mxx ; 0 scyy myy; 0 0 1]; + + +a00n = Hnorm*a00; +a10n = Hnorm*a10; +a11n = Hnorm*a11; +a01n = Hnorm*a01; + + +% Computation of the vanishing points: + +V1n = cross(cross(a00n,a10n),cross(a01n,a11n)); +V2n = cross(cross(a00n,a01n),cross(a10n,a11n)); + +V1 = inv_Hnorm*V1n; +V2 = inv_Hnorm*V2n; + + +% Normalizaion of the vanishing points: + +V1n = V1n/norm(V1n); +V2n = V2n/norm(V2n); + + +% Closed-form solution of the coefficients: + +alpha_x = (a10n(2)*a00n(1) - a10n(1)*a00n(2))/(V1n(2)*a10n(1)-V1n(1)*a10n(2)); + +alpha_y = (a01n(2)*a00n(1) - a01n(1)*a00n(2))/(V2n(2)*a01n(1)-V2n(1)*a01n(2)); + + +% Remaining Homography + +Hrem = [alpha_x*V1n alpha_y*V2n a00n]; + + +% Final homography: + +H = inv_Hnorm*Hrem; + diff --git a/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/compute_extrinsic.m b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/compute_extrinsic.m new file mode 100755 index 0000000..5217351 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/compute_extrinsic.m @@ -0,0 +1,123 @@ +function [omckk,Tckk,Rckk,H,x,ex,JJ] = compute_extrinsic(x_kk,X_kk,fc,cc,kc,alpha_c,MaxIter,thresh_cond), + +%compute_extrinsic +% +%[omckk,Tckk,Rckk,H,x,ex] = compute_extrinsic(x_kk,X_kk,fc,cc,kc,alpha_c) +% +%Computes the extrinsic parameters attached to a 3D structure X_kk given its projection +%on the image plane x_kk and the intrinsic camera parameters fc, cc and kc. +%Works with planar and non-planar structures. +% +%INPUT: x_kk: Feature locations on the images +% X_kk: Corresponding grid coordinates +% fc: Camera focal length +% cc: Principal point coordinates +% kc: Distortion coefficients +% alpha_c: Skew coefficient +% +%OUTPUT: omckk: 3D rotation vector attached to the grid positions in space +% Tckk: 3D translation vector attached to the grid positions in space +% Rckk: 3D rotation matrices corresponding to the omc vectors +% H: Homography between points on the grid and points on the image plane (in pixel) +% This makes sense only if the planar that is used in planar. +% x: Reprojections of the points on the image plane +% ex: Reprojection error: ex = x_kk - x; +% +%Method: Computes the normalized point coordinates, then computes the 3D pose +% +%Important functions called within that program: +% +%normalize: Computes the normalize image point coordinates. +% +%pose3D: Computes the 3D pose of the structure given the normalized image projection. +% +%project_points.m: Computes the 2D image projections of a set of 3D points + + + +if nargin < 8, + thresh_cond = inf; +end; + + +if nargin < 7, + MaxIter = 20; +end; + + +if nargin < 6, + alpha_c = 0; + if nargin < 5, + kc = zeros(4,1); + if nargin < 4, + cc = zeros(2,1); + if nargin < 3, + fc = ones(2,1); + if nargin < 2, + error('Need 2D projections and 3D points (in compute_extrinsic.m)'); + return; + end; + end; + end; + end; +end; + +% Initialization: + +[omckk,Tckk,Rckk] = compute_extrinsic_init(x_kk,X_kk,fc,cc,kc,alpha_c); + +% Refinement: + +[omckk,Tckk,Rckk,JJ] = compute_extrinsic_refine(omckk,Tckk,x_kk,X_kk,fc,cc,kc,alpha_c,MaxIter,thresh_cond); + + +% computation of the homography (not useful in the end) + +H = [Rckk(:,1:2) Tckk]; + +% Computes the reprojection error in pixels: + +x = project_points2(X_kk,omckk,Tckk,fc,cc,kc,alpha_c); + +ex = x_kk - x; + + +% Converts the homography in pixel units: + +KK = [fc(1) alpha_c*fc(1) cc(1);0 fc(2) cc(2); 0 0 1]; + +H = KK*H; + + + + +return; + + +% Test of compte extrinsic: + +Np = 4; +sx = 10; +sy = 10; +sz = 5; + +om = randn(3,1); +T = [0;0;100]; + +noise = 2/1000; + +XX = [sx*randn(1,Np);sy*randn(1,Np);sz*randn(1,Np)]; +xx = project_points(XX,om,T); + +xxn = xx + noise * randn(2,Np); + +[omckk,Tckk] = compute_extrinsic(xxn,XX); + +[om omckk om-omckk] +[T Tckk T-Tckk] + +figure(3); +plot(xx(1,:),xx(2,:),'r+'); +hold on; +plot(xxn(1,:),xxn(2,:),'g+'); +hold off; diff --git a/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/compute_extrinsic_init.m b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/compute_extrinsic_init.m new file mode 100755 index 0000000..2e6d821 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/compute_extrinsic_init.m @@ -0,0 +1,151 @@ +function [omckk,Tckk,Rckk] = compute_extrinsic_init(x_kk,X_kk,fc,cc,kc,alpha_c), + +%compute_extrinsic +% +%[omckk,Tckk,Rckk] = compute_extrinsic_init(x_kk,X_kk,fc,cc,kc,alpha_c) +% +%Computes the extrinsic parameters attached to a 3D structure X_kk given its projection +%on the image plane x_kk and the intrinsic camera parameters fc, cc and kc. +%Works with planar and non-planar structures. +% +%INPUT: x_kk: Feature locations on the images +% X_kk: Corresponding grid coordinates +% fc: Camera focal length +% cc: Principal point coordinates +% kc: Distortion coefficients +% alpha_c: Skew coefficient +% +%OUTPUT: omckk: 3D rotation vector attached to the grid positions in space +% Tckk: 3D translation vector attached to the grid positions in space +% Rckk: 3D rotation matrices corresponding to the omc vectors +% +%Method: Computes the normalized point coordinates, then computes the 3D pose +% +%Important functions called within that program: +% +%normalize: Computes the normalize image point coordinates. +% +%pose3D: Computes the 3D pose of the structure given the normalized image projection. +% +%project_points.m: Computes the 2D image projections of a set of 3D points + + + +if nargin < 6, + alpha_c = 0; + if nargin < 5, + kc = zeros(4,1); + if nargin < 4, + cc = zeros(2,1); + if nargin < 3, + fc = ones(2,1); + if nargin < 2, + error('Need 2D projections and 3D points (in compute_extrinsic.m)'); + return; + end; + end; + end; + end; +end; + + +% Compute the normalized coordinates: + +xn = normalize(x_kk,fc,cc,kc,alpha_c); + + + +Np = size(xn,2); + +%% Check for planarity of the structure: + +X_mean = mean(X_kk')'; + +Y = X_kk - (X_mean*ones(1,Np)); + +YY = Y*Y'; + +[U,S,V] = svd(YY); + +r = S(3,3)/S(2,2); + +if (r < 1e-3)|(Np < 6), %1e-3, %1e-4, %norm(X_kk(3,:)) < eps, % Test of planarity + + %fprintf(1,'Planar structure detected: r=%f\n',r); + + % Transform the plane to bring it in the Z=0 plane: + + R_transform = V'; + + if det(R_transform) < 0, R_transform = -R_transform; end; + + T_transform = -(R_transform)*X_mean; + + X_new = R_transform*X_kk + T_transform*ones(1,Np); + + + % Compute the planar homography: + + H = compute_homography (xn,X_new(1:2,:)); + + % De-embed the motion parameters from the homography: + + sc = mean([norm(H(:,1));norm(H(:,2))]); + + H = H/sc; + + omckk = rodrigues([H(:,1:2) cross(H(:,1),H(:,2))]); + Rckk = rodrigues(omckk); + Tckk = H(:,3); + + %If Xc = Rckk * X_new + Tckk, then Xc = Rckk * R_transform * X_kk + Tckk + T_transform + + Tckk = Tckk + Rckk* T_transform; + Rckk = Rckk * R_transform; + + omckk = rodrigues(Rckk); + Rckk = rodrigues(omckk); + + +else + + %fprintf(1,'Non planar structure detected: r=%f\n',r); + + % Computes an initial guess for extrinsic parameters (works for general 3d structure, not planar!!!): + % The DLT method is applied here!! + + J = zeros(2*Np,12); + + xX = (ones(3,1)*xn(1,:)).*X_kk; + yX = (ones(3,1)*xn(2,:)).*X_kk; + + J(1:2:end,[1 4 7]) = -X_kk'; + J(2:2:end,[2 5 8]) = X_kk'; + J(1:2:end,[3 6 9]) = xX'; + J(2:2:end,[3 6 9]) = -yX'; + J(1:2:end,12) = xn(1,:)'; + J(2:2:end,12) = -xn(2,:)'; + J(1:2:end,10) = -ones(Np,1); + J(2:2:end,11) = ones(Np,1); + + JJ = J'*J; + [U,S,V] = svd(JJ); + + RR = reshape(V(1:9,12),3,3); + + if det(RR) < 0, + V(:,12) = -V(:,12); + RR = -RR; + end; + + [Ur,Sr,Vr] = svd(RR); + + Rckk = Ur*Vr'; + + sc = norm(V(1:9,12)) / norm(Rckk(:)); + Tckk = V(10:12,12)/sc; + + omckk = rodrigues(Rckk); + Rckk = rodrigues(omckk); + +end; diff --git a/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/compute_extrinsic_refine.m b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/compute_extrinsic_refine.m new file mode 100755 index 0000000..a4d066c --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/compute_extrinsic_refine.m @@ -0,0 +1,113 @@ +function [omckk,Tckk,Rckk,JJ] = compute_extrinsic_refine(omc_init,Tc_init,x_kk,X_kk,fc,cc,kc,alpha_c,MaxIter,thresh_cond), + +%compute_extrinsic +% +%[omckk,Tckk,Rckk] = compute_extrinsic_refine(x_kk,X_kk,fc,cc,kc,alpha_c,MaxIter) +% +%Computes the extrinsic parameters attached to a 3D structure X_kk given its projection +%on the image plane x_kk and the intrinsic camera parameters fc, cc and kc. +%Works with planar and non-planar structures. +% +%INPUT: x_kk: Feature locations on the images +% X_kk: Corresponding grid coordinates +% fc: Camera focal length +% cc: Principal point coordinates +% kc: Distortion coefficients +% alpha_c: Skew coefficient +% MaxIter: Maximum number of iterations +% +%OUTPUT: omckk: 3D rotation vector attached to the grid positions in space +% Tckk: 3D translation vector attached to the grid positions in space +% Rckk: 3D rotation matrices corresponding to the omc vectors + +% +%Method: Computes the normalized point coordinates, then computes the 3D pose +% +%Important functions called within that program: +% +%normalize: Computes the normalize image point coordinates. +% +%pose3D: Computes the 3D pose of the structure given the normalized image projection. +% +%project_points.m: Computes the 2D image projections of a set of 3D points + + +if nargin < 10, + thresh_cond = inf; +end; + + +if nargin < 9, + MaxIter = 20; +end; + +if nargin < 8, + alpha_c = 0; + if nargin < 7, + kc = zeros(4,1); + if nargin < 6, + cc = zeros(2,1); + if nargin < 5, + fc = ones(2,1); + if nargin < 4, + error('Need 2D projections and 3D points (in compute_extrinsic_refine.m)'); + return; + end; + end; + end; + end; +end; + + +% Initialization: + +omckk = omc_init; +Tckk = Tc_init; + + +% Final optimization (minimize the reprojection error in pixel): +% through Gradient Descent: + +param = [omckk;Tckk]; + +change = 1; + +iter = 0; + +%keyboard; + +%fprintf(1,'Gradient descent iterations: '); + +while (change > 1e-10)&(iter < MaxIter), + + %fprintf(1,'%d...',iter+1); + + [x,dxdom,dxdT] = project_points2(X_kk,omckk,Tckk,fc,cc,kc,alpha_c); + + ex = x_kk - x; + + %keyboard; + + JJ = [dxdom dxdT]; + + if cond(JJ) > thresh_cond, + change = 0; + else + + JJ2 = JJ'*JJ; + + param_innov = inv(JJ2)*(JJ')*ex(:); + param_up = param + param_innov; + change = norm(param_innov)/norm(param_up); + param = param_up; + iter = iter + 1; + + omckk = param(1:3); + Tckk = param(4:6); + end; + +end; + +%fprintf(1,'\n'); + +Rckk = rodrigues(omckk); diff --git a/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/compute_homography.m b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/compute_homography.m new file mode 100755 index 0000000..fcc9003 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/compute_homography.m @@ -0,0 +1,163 @@ +function [H,Hnorm,inv_Hnorm] = compute_homography (m,M); + +%compute_homography +% +%[H,Hnorm,inv_Hnorm] = compute_homography (m,M) +% +%Computes the planar homography between the point coordinates on the plane (M) and the image +%point coordinates (m). +% +%INPUT: m: homogeneous coordinates in the image plane (3xN matrix) +% M: homogeneous coordinates in the plane in 3D (3xN matrix) +% +%OUTPUT: H: Homography matrix (3x3 homogeneous matrix) +% Hnorm: Normlization matrix used on the points before homography computation +% (useful for numerical stability is points in pixel coordinates) +% inv_Hnorm: The inverse of Hnorm +% +%Definition: m ~ H*M where "~" means equal up to a non zero scalar factor. +% +%Method: First computes an initial guess for the homography through quasi-linear method. +% Then, if the total number of points is larger than 4, optimize the solution by minimizing +% the reprojection error (in the least squares sense). +% +% +%Important functions called within that program: +% +%comp_distortion_oulu: Undistorts pixel coordinates. +% +%compute_homography.m: Computes the planar homography between points on the grid in 3D, and the image plane. +% +%project_points.m: Computes the 2D image projections of a set of 3D points, and also returns te Jacobian +% matrix (derivative with respect to the intrinsic and extrinsic parameters). +% This function is called within the minimization loop. + + + + +Np = size(m,2); + +if size(m,1)<3, + m = [m;ones(1,Np)]; +end; + +if size(M,1)<3, + M = [M;ones(1,Np)]; +end; + + +m = m ./ (ones(3,1)*m(3,:)); +M = M ./ (ones(3,1)*M(3,:)); + +% Prenormalization of point coordinates (very important): +% (Affine normalization) + +ax = m(1,:); +ay = m(2,:); + +mxx = mean(ax); +myy = mean(ay); +ax = ax - mxx; +ay = ay - myy; + +scxx = mean(abs(ax)); +scyy = mean(abs(ay)); + + +Hnorm = [1/scxx 0 -mxx/scxx;0 1/scyy -myy/scyy;0 0 1]; +inv_Hnorm = [scxx 0 mxx ; 0 scyy myy; 0 0 1]; + +mn = Hnorm*m; + +% Compute the homography between m and mn: + +% Build the matrix: + +L = zeros(2*Np,9); + +L(1:2:2*Np,1:3) = M'; +L(2:2:2*Np,4:6) = M'; +L(1:2:2*Np,7:9) = -((ones(3,1)*mn(1,:)).* M)'; +L(2:2:2*Np,7:9) = -((ones(3,1)*mn(2,:)).* M)'; + +if Np > 4, + L = L'*L; +end; + +[U,S,V] = svd(L); + +hh = V(:,9); +hh = hh/hh(9); + +Hrem = reshape(hh,3,3)'; +%Hrem = Hrem / Hrem(3,3); + +% Final homography: + +H = inv_Hnorm*Hrem; + + +%%% Homography refinement if there are more than 4 points: + +if Np > 4, + + % Final refinement: + + hhv = reshape(H',9,1); + hhv = hhv(1:8); + + for iter=1:10, + + mrep = H * M; + + J = zeros(2*Np,8); + + MMM = (M ./ (ones(3,1)*mrep(3,:))); + + J(1:2:2*Np,1:3) = -MMM'; + J(2:2:2*Np,4:6) = -MMM'; + + mrep = mrep ./ (ones(3,1)*mrep(3,:)); + + m_err = m(1:2,:) - mrep(1:2,:); + m_err = m_err(:); + + MMM2 = (ones(3,1)*mrep(1,:)) .* MMM; + MMM3 = (ones(3,1)*mrep(2,:)) .* MMM; + + J(1:2:2*Np,7:8) = MMM2(1:2,:)'; + J(2:2:2*Np,7:8) = MMM3(1:2,:)'; + + MMM = (M ./ (ones(3,1)*mrep(3,:)))'; + + hh_innov = inv(J'*J)*J'*m_err; + + hhv_up = hhv - hh_innov; + + H_up = reshape([hhv_up;1],3,3)'; + + %norm(m_err) + %norm(hh_innov) + + hhv = hhv_up; + H = H_up; + + end; + +end; + + + + + +return; + +%test of Jacobian + +mrep = H*M; +mrep = mrep ./ (ones(3,1)*mrep(3,:)); + +m_err = mrep(1:2,:) - m(1:2,:); +figure(8); +plot(m_err(1,:),m_err(2,:),'r+'); +std(m_err') diff --git a/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/cornerfinder.m b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/cornerfinder.m new file mode 100755 index 0000000..9bfa51f --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/cornerfinder.m @@ -0,0 +1,215 @@ +function [xc,good,bad,type] = cornerfinder(xt,I,wintx,winty,wx2,wy2); + +%[xc] = cornerfinder(xt,I); +% +%Finds the sub-pixel corners on the image I with initial guess xt +%xt and xc are 2xN matrices. The first component is the x coordinate +%(horizontal) and the second component is the y coordinate (vertical) +% +%Based on Harris corner finder method +% +%Finds corners to a precision below .1 pixel! +%Oct. 14th, 1997 - UPDATED to work with vertical and horizontal edges as well!!! +%Sept 1998 - UPDATED to handle diverged points: we keep the original points +%good is a binary vector indicating wether a feature point has been properly +%found. +% +%Add a zero zone of size wx2,wy2 +%July 15th, 1999 - Bug on the mask building... fixed + change to Gaussian mask with higher +%resolution and larger number of iterations. + + +% California Institute of Technology +% (c) Jean-Yves Bouguet -- Oct. 14th, 1997 + + + +line_feat = 1; % set to 1 to allow for extraction of line features. + +xt = xt'; +xt = fliplr(xt); + + +if nargin < 4, + winty = 5; + if nargin < 3, + wintx = 5; + end; +end; + + +if nargin < 6, + wx2 = -1; + wy2 = -1; +end; + + +%mask = ones(2*wintx+1,2*winty+1); +mask = exp(-((-wintx:wintx)'/(wintx)).^2) * exp(-((-winty:winty)/(winty)).^2); + + +if (wx2>0) & (wy2>0), + if ((wintx - wx2)>=2)&((winty - wy2)>=2), + mask(wintx+1-wx2:wintx+1+wx2,winty+1-wy2:winty+1+wy2)= zeros(2*wx2+1,2*wy2+1); + end; +end; + +offx = [-wintx:wintx]'*ones(1,2*winty+1); +offy = ones(2*wintx+1,1)*[-winty:winty]; + +resolution = 0.005; + +MaxIter = 10; + +[nx,ny] = size(I); +N = size(xt,1); + +xc = xt; % first guess... they don't move !!! + +type = zeros(1,N); + + +for i=1:N, + + v_extra = resolution + 1; % just larger than resolution + + compt = 0; % no iteration yet + + while (norm(v_extra) > resolution) & (compt 0, % the sub pixel + vIx = [itIx 1-itIx 0]'; % accuracy. + else + vIx = [0 1+itIx -itIx]'; + end; + if itIy > 0, + vIy = [itIy 1-itIy 0]; + else + vIy = [0 1+itIy -itIy]; + end; + + + % What if the sub image is not in? + + if (crIx-wintx-2 < 1), xmin=1; xmax = 2*wintx+5; + elseif (crIx+wintx+2 > nx), xmax = nx; xmin = nx-2*wintx-4; + else + xmin = crIx-wintx-2; xmax = crIx+wintx+2; + end; + + if (crIy-winty-2 < 1), ymin=1; ymax = 2*winty+5; + elseif (crIy+winty+2 > ny), ymax = ny; ymin = ny-2*winty-4; + else + ymin = crIy-winty-2; ymax = crIy+winty+2; + end; + + + SI = I(xmin:xmax,ymin:ymax); % The necessary neighborhood + SI = conv2(conv2(SI,vIx,'same'),vIy,'same'); + SI = SI(2:2*wintx+4,2:2*winty+4); % The subpixel interpolated neighborhood + [gy,gx] = gradient(SI); % The gradient image + gx = gx(2:2*wintx+2,2:2*winty+2); % extraction of the useful parts only + gy = gy(2:2*wintx+2,2:2*winty+2); % of the gradients + + px = cIx + offx; + py = cIy + offy; + + gxx = gx .* gx .* mask; + gyy = gy .* gy .* mask; + gxy = gx .* gy .* mask; + + + bb = [sum(sum(gxx .* px + gxy .* py)); sum(sum(gxy .* px + gyy .* py))]; + + a = sum(sum(gxx)); + b = sum(sum(gxy)); + c = sum(sum(gyy)); + + dt = a*c - b^2; + + xc2 = [c*bb(1)-b*bb(2) a*bb(2)-b*bb(1)]/dt; + + + %keyboard; + + if line_feat, + + G = [a b;b c]; + [U,S,V] = svd(G); + + %keyboard; + + % If non-invertible, then project the point onto the edge orthogonal: + + if (S(1,1)/S(2,2) > 50), + % projection operation: + xc2 = xc2 + sum((xc(i,:)-xc2).*(V(:,2)'))*V(:,2)'; + type(i) = 1; + end; + + end; + + + %keyboard; + +% G = [a b;b c]; +% [U,S,V] = svd(G); + + +% if S(1,1)/S(2,2) > 150, +% bb2 = U'*bb; +% xc2 = (V*[bb2(1)/S(1,1) ;0])'; +% else +% xc2 = [c*bb(1)-b*bb(2) a*bb(2)-b*bb(1)]/dt; +% end; + + + %if (abs(a)> 50*abs(c)), +% xc2 = [(c*bb(1)-b*bb(2))/dt xc(i,2)]; +% elseif (abs(c)> 50*abs(a)) +% xc2 = [xc(i,1) (a*bb(2)-b*bb(1))/dt]; +% else +% xc2 = [c*bb(1)-b*bb(2) a*bb(2)-b*bb(1)]/dt; +% end; + + %keyboard; + + v_extra = xc(i,:) - xc2; + + xc(i,:) = xc2; + +% keyboard; + + compt = compt + 1; + + end +end; + + +% check for points that diverge: + +delta_x = xc(:,1) - xt(:,1); +delta_y = xc(:,2) - xt(:,2); + +%keyboard; + + +bad = (abs(delta_x) > wintx) | (abs(delta_y) > winty); +good = ~bad; +in_bad = find(bad); + +% For the diverged points, keep the original guesses: + +xc(in_bad,:) = xt(in_bad,:); + +xc = fliplr(xc); +xc = xc'; + +bad = bad'; +good = good'; diff --git a/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/count_squares.m b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/count_squares.m new file mode 100755 index 0000000..0e226c0 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/count_squares.m @@ -0,0 +1,74 @@ +function ns = count_squares(I,x1,y1,x2,y2,win); + +%keyboard; + +[ny,nx] = size(I); + +lambda = [y1 - y2;x2 - x1;x1*y2 - x2*y1]; + +lambda = 1/sqrt(lambda(1)^2 + lambda(2)^2) * lambda; + +l1 = lambda + [0;0;win]; +l2 = lambda - [0;0;win]; + + +dx = x2-x1; +dy = y2 - y1; + + +if abs(dx) > abs(dy), + + if x2 > x1, + xs = x1:x2; + else + xs = x1:-1:x2; + end; + + ys = -(lambda(3) + lambda(1)*xs)/lambda(2); + +else + + if y2 > y1, + ys = y1:y2; + else + ys = y1:-1:y2; + end; + xs = -(lambda(3) + lambda(2)*ys)/lambda(1); + +end; + + + + Np = length(xs); + + xs_mat = ones(2*win + 1,1)*xs; + ys_mat = ones(2*win + 1,1)*ys; + + win_mat = (-win:win)'*ones(1,Np); + + + xs_mat2 = round(xs_mat - win_mat * lambda(1)); + ys_mat2 = round(ys_mat - win_mat * lambda(2)); + + ind_mat = (xs_mat2 - 1) * ny + ys_mat2; + + ima_patch = zeros(2*win + 1,Np); + + ima_patch(:) = I(ind_mat(:)); + + %ima2 = ima_patch(:,win+1:end-win); + + filtk = [ones(win,Np);zeros(1,Np);-ones(win,Np)]; + + out_f = sum(filtk.*ima_patch); + + out_f_f = conv2(out_f,[1/4 1/2 1/4],'same'); + + out_f_f = out_f_f(win+1:end-win); + + ns = length(find(((out_f_f(2:end)>=0)&(out_f_f(1:end-1)<0)) | ((out_f_f(2:end)<=0)&(out_f_f(1:end-1)>0))))+1; + + + + +return; diff --git a/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/data_calib.m b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/data_calib.m new file mode 100755 index 0000000..422769b --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/data_calib.m @@ -0,0 +1,92 @@ +%%% This script alets the user enter the name of the images (base name, numbering scheme,... + + +% Checks that there are some images in the directory: + +l_ras = dir('*ras'); +s_ras = size(l_ras,1); +l_bmp = dir('*bmp'); +s_bmp = size(l_bmp,1); +l_tif = dir('*tif'); +s_tif = size(l_tif,1); +l_pgm = dir('*pgm'); +s_pgm = size(l_pgm,1); +l_jpg = dir('*jpg'); +s_jpg = size(l_jpg,1); + +s_tot = s_ras + s_bmp + s_tif + s_pgm + s_jpg; + +if s_tot < 1, + fprintf(1,'No image in this directory in either ras, bmp, tif, pgm or jpg format. Change directory and try again.\n'); + break; +end; + + +% IF yes, display the directory content: + +dir; + +Nima_valid = 0; + +while (Nima_valid==0), + + fprintf(1,'\n'); + calib_name = input('Basename camera calibration images (without number nor suffix): ','s'); + + format_image = '0'; + + while format_image == '0', + + format_image = input('Image format: ([]=''r''=''ras'', ''b''=''bmp'', ''t''=''tif'', ''p''=''pgm'', ''j''=''jpg'', ''m''=''ppm'') ','s'); + + if isempty(format_image), + format_image = 'ras'; + end; + + if lower(format_image(1)) == 'm', + format_image = 'ppm'; + else + if lower(format_image(1)) == 'b', + format_image = 'bmp'; + else + if lower(format_image(1)) == 't', + format_image = 'tif'; + else + if lower(format_image(1)) == 'p', + format_image = 'pgm'; + else + if lower(format_image(1)) == 'j', + format_image = 'jpg'; + else + if lower(format_image(1)) == 'r', + format_image = 'ras'; + else + disp('Invalid image format'); + format_image = '0'; % Ask for format once again + end; + end; + end; + end; + end; + end; + end; + + + check_directory; + +end; + + + +%string_save = 'save calib_data n_ima type_numbering N_slots image_numbers format_image calib_name first_num'; + +%eval(string_save); + + + +if (Nima_valid~=0), + % Reading images: + + ima_read_calib; % may be launched from the toolbox itself +end; + diff --git a/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/error_analysis.m b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/error_analysis.m new file mode 100755 index 0000000..85feac5 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/error_analysis.m @@ -0,0 +1,182 @@ +%%% ERROR_ANALYSIS +%%% This simulation helps coputing the acturacies of calibration +%%% Run it after the main calibration + + + +N_runs = 200; + +%N_ima_active = 4; + +saving = 1; + +if 1, %~exist('fc_list'), % initialization + + % Initialization: + + load Calib_Results; + check_active_images; + + fc_list = []; + cc_list = []; + kc_list = []; + active_images_list = []; + + + for kk=1:n_ima, + + eval(['omc_list_' num2str(kk) ' = [];']); + eval(['Tc_list_' num2str(kk) ' = [];']); + + end; + + %sx = median(abs(ex(1,:)))*1.4836; + %sy = median(abs(ex(2,:)))*1.4836; + + sx = std(ex(1,:)); + sy = std(ex(2,:)); + + % Saving the feature locations: + + for kk = 1:n_ima, + + eval(['x_save_' num2str(kk) ' = x_' num2str(kk) ';']); + eval(['y_save_' num2str(kk) ' = y_' num2str(kk) ';']); + + end; + + active_images_save = active_images; + ind_active_save = ind_active; + + fc_save = fc; + cc_save = cc; + kc_save = kc; + KK_save = KK; + + +end; + + + + +%%% The main loop: + + +for ntrial = 1:N_runs, + + fprintf(1,'\nRun number: %d\n',ntrial); + fprintf(1, '----------\n'); + + for kk = 1:n_ima, + + eval(['y_kk = y_save_' num2str(kk) ';']) + + if active_images(kk) & ~isnan(y_kk(1,1)), + + Nkk = size(y_kk,2); + + x_kk_new = y_kk + [sx * randn(1,Nkk);sy*randn(1,Nkk)]; + + eval(['x_' num2str(kk) ' = x_kk_new;']); + + end; + + end; + + N_active = length(ind_active_save); + junk = randn(1,N_active); + [junk,junk2] = sort(junk); + + active_images = zeros(1,n_ima); + active_images(ind_active_save(junk2(1:N_ima_active))) = ones(1,N_ima_active); + + fc = fc_save; + cc = cc_save; + kc = kc_save; + KK = KK_save; + + go_calib_optim; + + fc_list = [fc_list fc]; + cc_list = [cc_list cc]; + kc_list = [kc_list kc]; + active_images_list = [active_images_list active_images']; + + for kk=1:n_ima, + + eval(['omc_list_' num2str(kk) ' = [ omc_list_' num2str(kk) ' omc_' num2str(kk) ' ];']); + eval(['Tc_list_' num2str(kk) ' = [ Tc_list_' num2str(kk) ' Tc_' num2str(kk) ' ];']); + + end; + +end; + + + + +if 0, + +% Restoring the feature locations: + +for kk = 1:n_ima, + + eval(['x_' num2str(kk) ' = x_save_' num2str(kk) ';']); + +end; + +fprintf(1,'\nFinal run (with the real data)\n'); +fprintf(1, '------------------------------\n'); + +active_images = active_images_save; +ind_active = ind_active_save; + +go_calib_optim; + +fc_list = [fc_list fc]; +cc_list = [cc_list cc]; +kc_list = [kc_list kc]; +active_images_list = [active_images_list active_images']; + +for kk=1:n_ima, + + eval(['omc_list_' num2str(kk) ' = [ omc_list_' num2str(kk) ' omc_' num2str(kk) ' ];']); + eval(['Tc_list_' num2str(kk) ' = [ Tc_list_' num2str(kk) ' Tc_' num2str(kk) ' ];']); + +end; + +end; + + + + + +if saving, + +disp(['Save Calibration accuracy results under Calib_Accuracies_' num2str(N_ima_active) '.mat']); + +string_save = ['save Calib_Accuracies_' num2str(N_ima_active) ' active_images n_ima N_ima_active N_runs active_images_list fc cc kc fc_list cc_list kc_list']; + +for kk = 1:n_ima, + string_save = [string_save ' Tc_list_' num2str(kk) ' omc_list_' num2str(kk) ' Tc_' num2str(kk) ' omc_' num2str(kk) ]; +end; + +eval(string_save); + +end; + + +return; + +std(fc_list') + +std(cc_list') + +std(kc_list') + +for kk = 1:n_ima, + + eval(['std(Tc_list_' num2str(kk) ''')']) + +end; + + diff --git a/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/export_calib_data.m b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/export_calib_data.m new file mode 100755 index 0000000..39506a8 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/export_calib_data.m @@ -0,0 +1,99 @@ +%% Export calibration data (corners + 3D coordinates) to +%% text files (in Willson-Heikkila's format or Zhang's format) + +%% Thanks to Michael Goesele (from the Max-Planck-Institut) for the original suggestion +%% of adding thsi export function to the toolbox. + + +if ~exist('n_ima'), + fprintf(1,'ERROR: No calibration data to export\n'); + +else + + check_active_images; + + check_extracted_images; + + check_active_images; + + fprintf(1,'Tool that exports calibration data to Willson-Heikkila or Zhang formats\n'); + + qformat = -1; + + while (qformat ~=0)&(qformat ~=1), + + fprintf(1,'Two possible formats of export: 0=Willson and Heikkila, 1=Zhang\n') + qformat = input('Format of export (enter 0 or 1): '); + + if isempty(qformat) + qformat = -1; + end; + + if (qformat ~=0)&(qformat ~=1), + + fprintf(1,'Invalid entry. Try again.\n') + + end; + + end; + + if qformat == 0, + + fprintf(1,'\nExport of calibration data to text files (Willson and Heikkila''s format)\n'); + outputfile = input('File basename: ','s'); + + for kk = ind_active, + + eval(['X_kk = X_' num2str(kk) ';']); + eval(['x_kk = x_' num2str(kk) ';']); + + Xx = [X_kk ; x_kk]'; + + file_name = [outputfile num2str(kk)]; + + disp(['Exporting calibration data (3D world + 2D image coordinates) of image ' num2str(kk) ' to file ' file_name '...']); + + eval(['save ' file_name ' Xx -ASCII']); + + end; + + else + + fprintf(1,'\nExport of calibration data to text files (Zhang''s format)\n'); + modelfile = input('File basename for the 3D world coordinates: ','s'); + datafile = input('File basename for the 2D image coordinates: ','s'); + + for kk = ind_active, + + eval(['X_kk = X_' num2str(kk) ';']); + eval(['x_kk = x_' num2str(kk) ';']); + + if ~exist(['n_sq_x_' num2str(kk)]), + n_sq_x = 1; + n_sq_y = size(X_kk,2); + else + eval(['n_sq_x = n_sq_x_' num2str(kk) ';']); + eval(['n_sq_y = n_sq_y_' num2str(kk) ';']); + end; + + X = reshape(X_kk(1,:)',n_sq_x+1,n_sq_y+1)'; + Y = reshape(X_kk(2,:)',n_sq_x+1,n_sq_y+1)'; + XY = reshape([X;Y],n_sq_y+1,2*(n_sq_x+1)); + + x = reshape(x_kk(1,:)',n_sq_x+1,n_sq_y+1)'; + y = reshape(x_kk(2,:)',n_sq_x+1,n_sq_y+1)'; + xy = reshape([x;y],n_sq_y+1,2*(n_sq_x+1)); + + disp(['Exporting calibration data of image ' num2str(kk) ' to files ' modelfile num2str(kk) '.txt and ' datafile num2str(kk) '.txt...']); + + eval(['save ' modelfile num2str(kk) '.txt XY -ASCII']); + eval(['save ' datafile num2str(kk) '.txt xy -ASCII']); + + end; + + +end; + +fprintf(1,'done\n'); + +end; diff --git a/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/ext_calib.m b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/ext_calib.m new file mode 100755 index 0000000..04d6319 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/ext_calib.m @@ -0,0 +1,152 @@ + +%%%%%%%%%%%%%%%%%%%% SHOW EXTRINSIC RESULTS %%%%%%%%%%%%%%%%%%%%%%%% + +if ~exist('n_ima')|~exist('fc'), + fprintf(1,'No calibration data available.\n'); + return; +end; + +check_active_images; + +if ~exist(['omc_' num2str(ind_active(1))]), + fprintf(1,'No calibration data available.\n'); + return; +end; + +%if ~exist('no_grid'), + no_grid = 0; +%end; + +if ~exist(['n_sq_x_' num2str(ind_active(1))]), + no_grid = 1; +end; + + +if 0, + +err_std = std(ex'); + +fprintf(1,'\n\nCalibration results without principal point estimation:\n\n'); +fprintf(1,'Focal Length: fc = [ %3.5f %3.5f]\n',fc); +fprintf(1,'Principal point: cc = [ %3.5f %3.5f]\n',cc); +fprintf(1,'Distortion: kc = [ %3.5f %3.5f %3.5f %3.5f]\n',kc); +fprintf(1,'Pixel error: err = [ %3.5f %3.5f]\n\n',err_std); + +end; + + +% Color code for each image: + +colors = 'brgkcm'; + + +%%% Show the extrinsic parameters + +if ~exist('dX'), + eval(['dX = norm(Tc_' num2str(ind_active(1)) ')/10;']); + dY = dX; +end; + +IP = 5*dX*([0 nx-1 nx-1 0 0 ; 0 0 ny-1 ny-1 0;1 1 1 1 1] - [cc;0]*ones(1,5)) ./ ([fc;1]*ones(1,5)); +BASE = 5*dX*([0 1 0 0 0 0;0 0 0 1 0 0;0 0 0 0 0 1]); +IP = reshape([IP;BASE(:,1)*ones(1,5);IP],3,15); + +figure(4); +[a,b] = view; + +figure(4); +plot3(BASE(1,:),BASE(3,:),-BASE(2,:),'b-','linewidth',2'); +hold on; +plot3(IP(1,:),IP(3,:),-IP(2,:),'r-','linewidth',2); +text(6*dX,0,0,'X_c'); +text(-dX,5*dX,0,'Z_c'); +text(0,0,-6*dX,'Y_c'); +text(-dX,-dX,dX,'O_c'); + + +for kk = 1:n_ima, + + if active_images(kk); + + if exist(['X_' num2str(kk)]) & exist(['omc_' num2str(kk)]), + + eval(['XX_kk = X_' num2str(kk) ';']); + + if ~isnan(XX_kk(1,1)) + + eval(['omc_kk = omc_' num2str(kk) ';']); + eval(['Tc_kk = Tc_' num2str(kk) ';']); + N_kk = size(XX_kk,2); + + if ~exist(['n_sq_x_' num2str(kk)]), + no_grid = 1; + else + eval(['n_sq_x = n_sq_x_' num2str(kk) ';']); + if isnan(n_sq_x(1)), + no_grid = 1; + end; + end; + + + if ~no_grid, + eval(['n_sq_x = n_sq_x_' num2str(kk) ';']); + eval(['n_sq_y = n_sq_y_' num2str(kk) ';']); + if (N_kk ~= ((n_sq_x+1)*(n_sq_y+1))), + no_grid = 1; + end; + end; + + if ~isnan(omc_kk(1,1)), + + R_kk = rodrigues(omc_kk); + + YY_kk = R_kk * XX_kk + Tc_kk * ones(1,length(XX_kk)); + + uu = [-dX;-dY;0]/2; + uu = R_kk * uu + Tc_kk; + + if ~no_grid, + YYx = zeros(n_sq_x+1,n_sq_y+1); + YYy = zeros(n_sq_x+1,n_sq_y+1); + YYz = zeros(n_sq_x+1,n_sq_y+1); + + YYx(:) = YY_kk(1,:); + YYy(:) = YY_kk(2,:); + YYz(:) = YY_kk(3,:); + + %keyboard; + + figure(4); + hhh= mesh(YYx,YYz,-YYy); + set(hhh,'edgecolor',colors(rem(kk-1,6)+1),'linewidth',1); %,'facecolor','none'); + %plot3(YY_kk(1,:),YY_kk(3,:),-YY_kk(2,:),['o' colors(rem(kk-1,6)+1)]); + text(uu(1),uu(3),-uu(2),num2str(kk),'fontsize',14,'color',colors(rem(kk-1,6)+1)); + else + + figure(4); + plot3(YY_kk(1,:),YY_kk(3,:),-YY_kk(2,:),['.' colors(rem(kk-1,6)+1)]); + text(uu(1),uu(3),-uu(2),num2str(kk),'fontsize',14,'color',colors(rem(kk-1,6)+1)); + + end; + + end; + + end; + + end; + + end; + +end; + +figure(4);rotate3d on; +axis('equal'); +title('Extrinsic parameters'); +%view(60,30); +view(a,b); +hold off; + +set(4,'Name','3D','NumberTitle','off'); + +%fprintf(1,'To generate the complete movie associated to the optimization loop, try: check_convergence;\n'); + diff --git a/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/extract_grid.m b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/extract_grid.m new file mode 100755 index 0000000..0cf9abe --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/extract_grid.m @@ -0,0 +1,234 @@ +function [x,X,n_sq_x,n_sq_y,ind_orig,ind_x,ind_y] = extract_grid(I,wintx,winty,fc,cc,kc,dX,dY); + +map = gray(256); + +minI = min(I(:)); +maxI = max(I(:)); + +Id = 255*(I - minI)/(maxI - minI); + + figure(2); + image(Id); + colormap(map); + + + if nargin < 2, + + disp('Window size for corner finder (wintx and winty):'); + wintx = input('wintx ([] = 5) = '); + if isempty(wintx), wintx = 5; end; + wintx = round(wintx); + winty = input('winty ([] = 5) = '); + if isempty(winty), winty = 5; end; + winty = round(winty); + + fprintf(1,'Window size = %dx%d\n',2*wintx+1,2*winty+1); + + end; + + + + title('Click on the four extreme corners of the rectangular pattern...'); + + disp('Click on the four extreme corners of the rectangular complete pattern...'); + + [x,y] = ginput3(4); + + [Xc,good,bad,type] = cornerfinder([x';y'],I,winty,wintx); % the four corners + + x = Xc(1,:)'; + y = Xc(2,:)'; + + [y,indy] = sort(y); + x = x(indy); + + if (x(2) > x(1)), + x4 = x(1);y4 = y(1); x3 = x(2); y3 = y(2); + else + x4 = x(2);y4 = y(2); x3 = x(1); y3 = y(1); + end; + if (x(3) > x(4)), + x2 = x(3);y2 = y(3); x1 = x(4); y1 = y(4); + else + x2 = x(4);y2 = y(4); x1 = x(3); y1 = y(3); + end; + + x = [x1;x2;x3;x4]; + y = [y1;y2;y3;y4]; + + + figure(2); hold on; + plot([x;x(1)],[y;y(1)],'g-'); + plot(x,y,'og'); + hx=text((x(4)+x(3))/2,(y(4)+y(3))/2 - 20,'X'); + set(hx,'color','g','Fontsize',14); + hy=text((x(4)+x(1))/2-20,(y(4)+y(1))/2,'Y'); + set(hy,'color','g','Fontsize',14); + hold off; + + + % Try to automatically count the number of squares in the grid + + n_sq_x1 = count_squares(I,x1,y1,x2,y2,wintx); + n_sq_x2 = count_squares(I,x3,y3,x4,y4,wintx); + n_sq_y1 = count_squares(I,x2,y2,x3,y3,wintx); + n_sq_y2 = count_squares(I,x4,y4,x1,y1,wintx); + + + + % If could not count the number of squares, enter manually + + if (n_sq_x1~=n_sq_x2)|(n_sq_y1~=n_sq_y2), + + + disp('Could not count the number of squares in the grid. Enter manually.'); + n_sq_x = input('Number of squares along the X direction ([]=10) = '); %6 + if isempty(n_sq_x), n_sq_x = 10; end; + n_sq_y = input('Number of squares along the Y direction ([]=10) = '); %6 + if isempty(n_sq_y), n_sq_y = 10; end; + + else + + n_sq_x = n_sq_x1; + n_sq_y = n_sq_y1; + + end; + + if ~exist('dX')|~exist('dY'), + + % Enter the size of each square + + dX = input(['Size dX of each square along the X direction ([]=30mm) = ']); + dY = input(['Size dY of each square along the Y direction ([]=30mm) = ']); + if isempty(dX), dX = 30; end; + if isempty(dY), dY = 30; end; + + end; + + + % Compute the inside points through computation of the planar homography (collineation) + + a00 = [x(1);y(1);1]; + a10 = [x(2);y(2);1]; + a11 = [x(3);y(3);1]; + a01 = [x(4);y(4);1]; + + + % Compute the planart collineation: (return the normalization matrice as well) + + [Homo,Hnorm,inv_Hnorm] = compute_homography ([a00 a10 a11 a01],[0 1 1 0;0 0 1 1;1 1 1 1]); + + + % Build the grid using the planar collineation: + + x_l = ((0:n_sq_x)'*ones(1,n_sq_y+1))/n_sq_x; + y_l = (ones(n_sq_x+1,1)*(0:n_sq_y))/n_sq_y; + pts = [x_l(:) y_l(:) ones((n_sq_x+1)*(n_sq_y+1),1)]'; + + XX = Homo*pts; + XX = XX(1:2,:) ./ (ones(2,1)*XX(3,:)); + + + % Complete size of the rectangle + + W = n_sq_x*dX; + L = n_sq_y*dY; + + + + if nargin < 6, + + %%%%%%%%%%%%%%%%%%%%%%%% ADDITIONAL STUFF IN THE CASE OF HIGHLY DISTORTED IMAGES %%%%%%%%%%%%% + figure(2); + hold on; + plot(XX(1,:),XX(2,:),'r+'); + title('The red crosses should be close to the image corners'); + hold off; + + disp('If the guessed grid corners (red crosses on the image) are not close to the actual corners,'); + disp('it is necessary to enter an initial guess for the radial distortion factor kc (useful for subpixel detection)'); + quest_distort = input('Need of an initial guess for distortion? ([]=no, other=yes) '); + + quest_distort = ~isempty(quest_distort); + + if quest_distort, + % Estimation of focal length: + c_g = [size(I,2);size(I,1)]/2 + .5; + f_g = Distor2Calib(0,[[x(1) x(2) x(4) x(3)] - c_g(1);[y(1) y(2) y(4) y(3)] - c_g(2)],1,1,4,W,L,[-W/2 W/2 W/2 -W/2;L/2 L/2 -L/2 -L/2; 0 0 0 0],100,1,1); + f_g = mean(f_g); + script_fit_distortion; + end; + %%%%%%%%%%%%%%%%%%%%% END ADDITIONAL STUFF IN THE CASE OF HIGHLY DISTORTED IMAGES %%%%%%%%%%%%% + + else + + xy_corners_undist = comp_distortion_oulu([(x' - cc(1))/fc(1);(y'-cc(2))/fc(1)],kc); + + xu = xy_corners_undist(1,:)'; + yu = xy_corners_undist(2,:)'; + + [XXu] = projectedGrid ( [xu(1);yu(1)], [xu(2);yu(2)],[xu(3);yu(3)], [xu(4);yu(4)],n_sq_x+1,n_sq_y+1); % The full grid + + r2 = sum(XXu.^2); + XX = (ones(2,1)*(1 + kc(1) * r2 + kc(2) * (r2.^2))) .* XXu; + XX(1,:) = fc(1)*XX(1,:)+cc(1); + XX(2,:) = fc(2)*XX(2,:)+cc(2); + + end; + + + Np = (n_sq_x+1)*(n_sq_y+1); + + disp('Corner extraction...'); + + grid_pts = cornerfinder(XX,I,winty,wintx); %%% Finds the exact corners at every points! + + grid_pts = grid_pts - 1; % subtract 1 to bring the origin to (0,0) instead of (1,1) in matlab (not necessary in C) + + ind_corners = [1 n_sq_x+1 (n_sq_x+1)*n_sq_y+1 (n_sq_x+1)*(n_sq_y+1)]; % index of the 4 corners + ind_orig = (n_sq_x+1)*n_sq_y + 1; + xorig = grid_pts(1,ind_orig); + yorig = grid_pts(2,ind_orig); + dxpos = mean([grid_pts(:,ind_orig) grid_pts(:,ind_orig+1)]'); + dypos = mean([grid_pts(:,ind_orig) grid_pts(:,ind_orig-n_sq_x-1)]'); + + + ind_x = (n_sq_x+1)*(n_sq_y + 1); + ind_y = 1; + + x_box_kk = [grid_pts(1,:)-(wintx+.5);grid_pts(1,:)+(wintx+.5);grid_pts(1,:)+(wintx+.5);grid_pts(1,:)-(wintx+.5);grid_pts(1,:)-(wintx+.5)]; + y_box_kk = [grid_pts(2,:)-(winty+.5);grid_pts(2,:)-(winty+.5);grid_pts(2,:)+(winty+.5);grid_pts(2,:)+(winty+.5);grid_pts(2,:)-(winty+.5)]; + + + figure(3); + image(Id); colormap(map); hold on; + plot(grid_pts(1,:)+1,grid_pts(2,:)+1,'r+'); + plot(x_box_kk+1,y_box_kk+1,'-b'); + plot(grid_pts(1,ind_corners)+1,grid_pts(2,ind_corners)+1,'mo'); + plot(xorig+1,yorig+1,'*m'); + h = text(xorig-15,yorig-15,'O'); + set(h,'Color','m','FontSize',14); + h2 = text(dxpos(1)-10,dxpos(2)-10,'dX'); + set(h2,'Color','g','FontSize',14); + h3 = text(dypos(1)-25,dypos(2)-3,'dY'); + set(h3,'Color','g','FontSize',14); + xlabel('Xc (in camera frame)'); + ylabel('Yc (in camera frame)'); + title('Extracted corners'); + zoom on; + drawnow; + hold off; + + + Xi = reshape(([0:n_sq_x]*dX)'*ones(1,n_sq_y+1),Np,1)'; + Yi = reshape(ones(n_sq_x+1,1)*[n_sq_y:-1:0]*dY,Np,1)'; + Zi = zeros(1,Np); + + Xgrid = [Xi;Yi;Zi]; + + + % All the point coordinates (on the image, and in 3D) - for global optimization: + + x = grid_pts; + X = Xgrid; + diff --git a/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/extract_parameters.m b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/extract_parameters.m new file mode 100755 index 0000000..035b97d --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/extract_parameters.m @@ -0,0 +1,46 @@ + +%%% Extraction of the final intrinsic and extrinsic paramaters: + +check_active_images; + +fc = solution(1:2);%*** +cc = solution(3:4);%*** +alpha_c = solution(5);%*** +kc = solution(6:9);%*** + + +% Calibration matrix: + +KK = [fc(1) fc(1)*alpha_c cc(1);0 fc(2) cc(2); 0 0 1]; +inv_KK = inv(KK); + +% Extract the extrinsic paramters, and recomputer the collineations + +for kk = 1:n_ima, + + if active_images(kk), + + omckk = solution(15+6*(kk-1) + 1:15+6*(kk-1) + 3);%*** + Tckk = solution(15+6*(kk-1) + 4:15+6*(kk-1) + 6);%*** + + Rckk = rodrigues(omckk); + + Hkk = KK * [Rckk(:,1) Rckk(:,2) Tckk]; + + Hkk = Hkk / Hkk(3,3); + + else + + omckk = NaN*ones(3,1); + Tckk = NaN*ones(3,1); + Rckk = NaN*ones(3,3); + Hkk = NaN*ones(3,3); + + end; + + eval(['omc_' num2str(kk) ' = omckk;']); + eval(['Rc_' num2str(kk) ' = Rckk;']); + eval(['Tc_' num2str(kk) ' = Tckk;']); + eval(['H_' num2str(kk) '= Hkk;']); + +end; diff --git a/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/extract_parameters3D.m b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/extract_parameters3D.m new file mode 100755 index 0000000..841c6ab --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/extract_parameters3D.m @@ -0,0 +1,36 @@ + +%%% Extraction of the final intrinsic and extrinsic paramaters: + + +fc = solution(1:2); +kc = solution(3:6); +cc = solution(6*n_ima + 4 +3:6*n_ima + 5 +3); + +% Calibration matrix: + +KK = [fc(1) 0 cc(1);0 fc(2) cc(2); 0 0 1]; +inv_KK = inv(KK); + +% Extract the extrinsic paramters, and recomputer the collineations + +for kk = 1:n_ima, + + omckk = solution(4+6*(kk-1) + 3:6*kk + 3); + + Tckk = solution(6*kk+1 + 3:6*kk+3 + 3); + + Rckk = rodrigues(omckk); + + Hlkk = KK * [Rckk(:,1) Rckk(:,2) Tckk]; + + Hlkk = Hlkk / Hlkk(3,3); + + eval(['omc_' num2str(kk) ' = omckk;']); + eval(['Rc_' num2str(kk) ' = Rckk;']); + eval(['Tc_' num2str(kk) ' = Tckk;']); + + eval(['Hl_' num2str(kk) '=Hlkk;']); + +end; + + diff --git a/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/extrinsic_computation.m b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/extrinsic_computation.m new file mode 100755 index 0000000..fbba78e --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/extrinsic_computation.m @@ -0,0 +1,185 @@ +%%% INPUT THE IMAGE FILE NAME: + +if ~exist('fc')|~exist('cc')|~exist('kc')|~exist('alpha_c'), + fprintf(1,'No intrinsic camera parameters available.\n'); + return; +end; + +dir; + +fprintf(1,'\n'); +disp('Computation of the extrinsic parameters from an image of a pattern'); +disp('The intrinsic camera parameters are assumed to be known (previously computed)'); + +fprintf(1,'\n'); +image_name = input('Image name (full name without extension): ','s'); + +format_image2 = '0'; + +while format_image2 == '0', + + format_image2 = input('Image format: ([]=''r''=''ras'', ''b''=''bmp'', ''t''=''tif'', ''p''=''pgm'', ''j''=''jpg'', ''m''=''ppm'') ','s'); + + if isempty(format_image2), + format_image2 = 'ras'; + end; + + if lower(format_image2(1)) == 'm', + format_image2 = 'ppm'; + else + if lower(format_image2(1)) == 'b', + format_image2 = 'bmp'; + else + if lower(format_image2(1)) == 't', + format_image2 = 'tif'; + else + if lower(format_image2(1)) == 'p', + format_image2 = 'pgm'; + else + if lower(format_image2(1)) == 'j', + format_image2 = 'jpg'; + else + if lower(format_image2(1)) == 'r', + format_image2 = 'ras'; + else + disp('Invalid image format'); + format_image2 = '0'; % Ask for format once again + end; + end; + end; + end; + end; + end; +end; + +ima_name = [image_name '.' format_image2]; + + +%%% READ IN IMAGE: + +if format_image2(1) == 'p', + if format_image2(2) == 'p', + I = double(loadppm(ima_name)); + else + I = double(loadpgm(ima_name)); + end; +else + if format_image2(1) == 'r', + I = readras(ima_name); + else + I = double(imread(ima_name)); + end; +end; + +if size(I,3)>1, + I = I(:,:,2); +end; + + +%%% EXTRACT GRID CORNERS: + +fprintf(1,'\nExtraction of the grid corners on the image\n'); + +disp('Window size for corner finder (wintx and winty):'); +wintx = input('wintx ([] = 5) = '); +if isempty(wintx), wintx = 5; end; +wintx = round(wintx); +winty = input('winty ([] = 5) = '); +if isempty(winty), winty = 5; end; +winty = round(winty); + +fprintf(1,'Window size = %dx%d\n',2*wintx+1,2*winty+1); + +[x_ext,X_ext,n_sq_x,n_sq_y,ind_orig,ind_x,ind_y] = extract_grid(I,wintx,winty,fc,cc,kc); + + + +%%% Computation of the Extrinsic Parameters attached to the grid: + +[omc_ext,Tc_ext,Rc_ext,H_ext] = compute_extrinsic(x_ext,X_ext,fc,cc,kc,alpha_c); + + +%%% Reproject the points on the image: + +[x_reproj] = project_points2(X_ext,omc_ext,Tc_ext,fc,cc,kc,alpha_c); + +err_reproj = x_ext - x_reproj; + +err_std2 = std(err_reproj')'; + + +Basis = [X_ext(:,[ind_orig ind_x ind_orig ind_y ind_orig ])]; + +VX = Basis(:,2) - Basis(:,1); +VY = Basis(:,4) - Basis(:,1); + +nX = norm(VX); +nY = norm(VY); + +VZ = min(nX,nY) * cross(VX/nX,VY/nY); + +Basis = [Basis VZ]; + +[x_basis] = project_points2(Basis,omc_ext,Tc_ext,fc,cc,kc,alpha_c); + +dxpos = (x_basis(:,2) + x_basis(:,1))/2; +dypos = (x_basis(:,4) + x_basis(:,3))/2; +dzpos = (x_basis(:,6) + x_basis(:,5))/2; + + + +figure(2); +image(I); +colormap(gray(256)); +hold on; +plot(x_ext(1,:)+1,x_ext(2,:)+1,'r+'); +plot(x_reproj(1,:)+1,x_reproj(2,:)+1,'yo'); +h = text(x_ext(1,ind_orig)-25,x_ext(2,ind_orig)-25,'O'); +set(h,'Color','g','FontSize',14); +h2 = text(dxpos(1)+1,dxpos(2)-30,'X'); +set(h2,'Color','g','FontSize',14); +h3 = text(dypos(1)-30,dypos(2)+1,'Y'); +set(h3,'Color','g','FontSize',14); +h4 = text(dzpos(1)-10,dzpos(2)-20,'Z'); +set(h4,'Color','g','FontSize',14); +plot(x_basis(1,:)+1,x_basis(2,:)+1,'g-','linewidth',2); +title('Image points (+) and reprojected grid points (o)'); +hold off; + + +fprintf(1,'\n\nExtrinsic parameters:\n\n'); +fprintf(1,'Translation vector: Tc_ext = [ %3.6f \t %3.6f \t %3.6f ]\n',Tc_ext); +fprintf(1,'Rotation vector: omc_ext = [ %3.6f \t %3.6f \t %3.6f ]\n',omc_ext); +fprintf(1,'Rotation matrix: Rc_ext = [ %3.6f \t %3.6f \t %3.6f\n',Rc_ext(1,:)'); +fprintf(1,' %3.6f \t %3.6f \t %3.6f\n',Rc_ext(2,:)'); +fprintf(1,' %3.6f \t %3.6f \t %3.6f ]\n',Rc_ext(3,:)'); +fprintf(1,'Pixel error: err = [ %3.5f \t %3.5f ]\n\n',err_std2); + + + + + +return; + + +% Stores the results: + +kk = 1; + +% Stores location of grid wrt camera: + +eval(['omc_' num2str(kk) ' = omc_ext;']); +eval(['Tc_' num2str(kk) ' = Tc_ext;']); + +% Stores the projected points: + +eval(['y_' num2str(kk) ' = x_reproj;']); +eval(['X_' num2str(kk) ' = X_ext;']); +eval(['x_' num2str(kk) ' = x_ext;']); + + +% Organize the points in a grid: + +eval(['n_sq_x_' num2str(kk) ' = n_sq_x;']); +eval(['n_sq_y_' num2str(kk) ' = n_sq_y;']); + \ No newline at end of file diff --git a/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/fixallvariables.m b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/fixallvariables.m new file mode 100755 index 0000000..b5808f3 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/fixallvariables.m @@ -0,0 +1,19 @@ +% Code that clears all empty or NaN variables + +varlist = whos; + +if ~isempty(varlist), + + Nvar = size(varlist,1); + + for c_var = 1:Nvar, + + var2fix = varlist(c_var).name; + + fixvariable; + + end; + +end; + +clear varlist var2fix Nvar c_var \ No newline at end of file diff --git a/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/fixvariable.m b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/fixvariable.m new file mode 100755 index 0000000..2213431 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/fixvariable.m @@ -0,0 +1,18 @@ +% Code that clears an empty variable, or a NaN vsriable. +% Does not clear structures, or cells. + +if exist('var2fix'), + if eval(['exist(''' var2fix ''') == 1']), + if eval(['isempty(' var2fix ')']), + eval(['clear ' var2fix ]); + else + if eval(['~isstruct(' var2fix ')']), + if eval(['~iscell(' var2fix ')']), + if eval(['isnan(' var2fix '(1))']), + eval(['clear ' var2fix ]); + end; + end; + end; + end; + end; +end; diff --git a/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/ginput3.m b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/ginput3.m new file mode 100755 index 0000000..56fe496 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/ginput3.m @@ -0,0 +1,216 @@ +function [out1,out2,out3] = ginput2(arg1) +%GINPUT Graphical input from mouse. +% [X,Y] = GINPUT(N) gets N points from the current axes and returns +% the X- and Y-coordinates in length N vectors X and Y. The cursor +% can be positioned using a mouse (or by using the Arrow Keys on some +% systems). Data points are entered by pressing a mouse button +% or any key on the keyboard except carriage return, which terminates +% the input before N points are entered. +% +% [X,Y] = GINPUT gathers an unlimited number of points until the +% return key is pressed. +% +% [X,Y,BUTTON] = GINPUT(N) returns a third result, BUTTON, that +% contains a vector of integers specifying which mouse button was +% used (1,2,3 from left) or ASCII numbers if a key on the keyboard +% was used. + +% Copyright (c) 1984-96 by The MathWorks, Inc. +% $Revision: 5.18 $ $Date: 1996/11/10 17:48:08 $ + +% Fixed version by Jean-Yves Bouguet to have a cross instead of 2 lines +% More visible for images + +P = NaN*ones(16,16); +P(1:15,1:15) = 2*ones(15,15); +P(2:14,2:14) = ones(13,13); +P(3:13,3:13) = NaN*ones(11,11); +P(6:10,6:10) = 2*ones(5,5); +P(7:9,7:9) = 1*ones(3,3); + +out1 = []; out2 = []; out3 = []; y = []; +c = computer; +if ~strcmp(c(1:2),'PC') & ~strcmp(c(1:2),'MA') + tp = get(0,'TerminalProtocol'); +else + tp = 'micro'; +end + +if ~strcmp(tp,'none') & ~strcmp(tp,'x') & ~strcmp(tp,'micro'), + if nargout == 1, + if nargin == 1, + eval('out1 = trmginput(arg1);'); + else + eval('out1 = trmginput;'); + end + elseif nargout == 2 | nargout == 0, + if nargin == 1, + eval('[out1,out2] = trmginput(arg1);'); + else + eval('[out1,out2] = trmginput;'); + end + if nargout == 0 + out1 = [ out1 out2 ]; + end + elseif nargout == 3, + if nargin == 1, + eval('[out1,out2,out3] = trmginput(arg1);'); + else + eval('[out1,out2,out3] = trmginput;'); + end + end +else + + fig = gcf; + figure(gcf); + + if nargin == 0 + how_many = -1; + b = []; + else + how_many = arg1; + b = []; + if isstr(how_many) ... + | size(how_many,1) ~= 1 | size(how_many,2) ~= 1 ... + | ~(fix(how_many) == how_many) ... + | how_many < 0 + error('Requires a positive integer.') + end + if how_many == 0 + ptr_fig = 0; + while(ptr_fig ~= fig) + ptr_fig = get(0,'PointerWindow'); + end + scrn_pt = get(0,'PointerLocation'); + loc = get(fig,'Position'); + pt = [scrn_pt(1) - loc(1), scrn_pt(2) - loc(2)]; + out1 = pt(1); y = pt(2); + elseif how_many < 0 + error('Argument must be a positive integer.') + end + end + +pointer = get(gcf,'pointer'); + +set(gcf,'Pointer','custom','PointerShapeCData',P,'PointerShapeHotSpot',[8,8]); +%set(gcf,'pointer','crosshair'); + fig_units = get(fig,'units'); + char = 0; + + while how_many ~= 0 + % Use no-side effect WAITFORBUTTONPRESS + waserr = 0; + eval('keydown = wfbp;', 'waserr = 1;'); + if(waserr == 1) + if(ishandle(fig)) + set(fig,'pointer',pointer,'units',fig_units); + error('Interrupted'); + else + error('Interrupted by figure deletion'); + end + end + + ptr_fig = get(0,'CurrentFigure'); + if(ptr_fig == fig) + if keydown + char = get(fig, 'CurrentCharacter'); + button = abs(get(fig, 'CurrentCharacter')); + scrn_pt = get(0, 'PointerLocation'); + set(fig,'units','pixels') + loc = get(fig, 'Position'); + pt = [scrn_pt(1) - loc(1), scrn_pt(2) - loc(2)]; + set(fig,'CurrentPoint',pt); + else + button = get(fig, 'SelectionType'); + if strcmp(button,'open') + button = b(length(b)); + elseif strcmp(button,'normal') + button = 1; + elseif strcmp(button,'extend') + button = 2; + elseif strcmp(button,'alt') + button = 3; + else + error('Invalid mouse selection.') + end + end + pt = get(gca, 'CurrentPoint'); + + how_many = how_many - 1; + + if(char == 13) % & how_many ~= 0) + % if the return key was pressed, char will == 13, + % and that's our signal to break out of here whether + % or not we have collected all the requested data + % points. + % If this was an early breakout, don't include + % the key info in the return arrays. + % We will no longer count it if it's the last input. + break; + end + + out1 = [out1;pt(1,1)]; + y = [y;pt(1,2)]; + b = [b;button]; + end + end + + set(fig,'pointer',pointer,'units',fig_units); + + if nargout > 1 + out2 = y; + if nargout > 2 + out3 = b; + end + else + out1 = [out1 y]; + end + +end + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +function key = wfbp +%WFBP Replacement for WAITFORBUTTONPRESS that has no side effects. + +% Remove figure button functions +fprops = {'windowbuttonupfcn','buttondownfcn', ... + 'windowbuttondownfcn','windowbuttonmotionfcn'}; +fig = gcf; +fvals = get(fig,fprops); +set(fig,fprops,{'','','',''}) + +% Remove all other buttondown functions +ax = findobj(fig,'type','axes'); +if isempty(ax) + ch = {}; +else + ch = get(ax,{'Children'}); +end +for i=1:length(ch), + ch{i} = ch{i}(:)'; +end +h = [ax(:)',ch{:}]; +vals = get(h,{'buttondownfcn'}); +mt = repmat({''},size(vals)); +set(h,{'buttondownfcn'},mt); + +% Now wait for that buttonpress, and check for error conditions +waserr = 0; +eval(['if nargout==0,', ... + ' waitforbuttonpress,', ... + 'else,', ... + ' keydown = waitforbuttonpress;',... + 'end' ], 'waserr = 1;'); + +% Put everything back +if(ishandle(fig)) + set(fig,fprops,fvals) + set(h,{'buttondownfcn'},vals) +end + +if(waserr == 1) + error('Interrupted'); +end + +if nargout>0, key = keydown; end +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% diff --git a/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/go_calib_optim.m b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/go_calib_optim.m new file mode 100755 index 0000000..ad19f64 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/go_calib_optim.m @@ -0,0 +1,139 @@ +%go_calib_optim +% +%Main calibration function. Computes the intrinsic andextrinsic parameters. +%Runs as a script. +% +%INPUT: x_1,x_2,x_3,...: Feature locations on the images +% X_1,X_2,X_3,...: Corresponding grid coordinates +% +%OUTPUT: fc: Camera focal length +% cc: Principal point coordinates +% kc: Distortion coefficients +% KK: The camera matrix (containing fc and cc) +% omc_1,omc_2,omc_3,...: 3D rotation vectors attached to the grid positions in space +% Tc_1,Tc_2,Tc_3,...: 3D translation vectors attached to the grid positions in space +% Rc_1,Rc_2,Rc_3,...: 3D rotation matrices corresponding to the omc vectors +% +%Method: Minimizes the pixel reprojection error in the least squares sense over the intrinsic +% camera parameters, and the extrinsic parameters (3D locations of the grids in space) +% +%Note: If the intrinsic camera parameters (fc, cc, kc) do not exist before, they are initialized through +% the function init_intrinsic_param.m. Otherwise, the variables in memory are used as initial guesses. +% +%Note: The row vector active_images consists of zeros and ones. To deactivate an image, set the +% corresponding entry in the active_images vector to zero. +% +%VERY IMPORTANT: This function works for 2D and 3D calibration rigs, except for init_intrinsic_param.m +%that is so far implemented to work only with 2D rigs. +%In the future, a more general function will be there. +%For now, if using a 3D calibration rig, set quick_init to 1 for an easy initialization of the focal length + + +if ~exist('n_ima'), + data_calib; % Load the images + click_calib; % Extract the corners +end; + + +check_active_images; + +check_extracted_images; + +check_active_images; + + +desactivated_images = []; + + +if ~exist('center_optim'), + center_optim = 1; %%% Set this variable to 0 if your do not want to estimate the principal point + %%% Required when using one image, and VERY RECOMMENDED WHEN USING LESS THAN 4 images +end; + +% Check 3D-ness of the calibration rig: +rig3D = 0; +for kk = ind_active, + eval(['X_kk = X_' num2str(kk) ';']); + if is3D(X_kk), + rig3D = 1; + end; +end; + + +if center_optim & (length(ind_active) < 2) & ~rig3D, + fprintf(1,'\nPrincipal point rejected from the optimization when using one image and planar rig (center_optim = 1).\n'); + center_optim = 0; %%% when using a single image, please, no principal point estimation!!! + est_alpha = 0; +end; + +if ~exist('dont_ask'), + dont_ask = 0; +end; + +if center_optim & (length(ind_active) < 5), + fprintf(1,'\nThe principal point estimation may be unreliable (using less than 5 images for calibration).\n'); + if ~dont_ask, + quest = input('Are you sure you want to keep the principal point in the optimization process? ([]=yes, other=no) '); + center_optim = isempty(quest); + end; +end; + +if center_optim, + fprintf(1,'\nINFO: To reject the principal point from the optimization, set center_optim = 0 in go_calib_optim.m\n'); +end; + +if ~exist('est_alpha'), + est_alpha = 0; % by default, do not estimate skew +end; + +if ~center_optim & (est_alpha), + fprintf(1,'WARNING: Since there is no principal point estimation, no skew estimation (est_alpha = 0)\n'); + est_alpha = 0; +else + if ~est_alpha, + fprintf(1,'WARNING: Skew not optimized. Check variable est_alpha.\n'); + alpha_c = 0; + else + fprintf(1,'WARNING: Skew is optimized. To disable skew estimation, set est_alpha=0.\n'); + end; +end; + + +if ~exist('est_dist'); + est_dist = [1;1;1;1]; +end; +if ~prod(est_dist), + fprintf(1,'\nWARNING: Distortion not fully estimated. Check variable est_dist.\n'); +end; + + + + +%%% MAIN OPTIMIZATION CALL!!!!! (look into this function for the details of implementation) +go_calib_optim_iter; + + + +if ~isempty(desactivated_images), + + param_list_save = param_list; + + fprintf(1,'\nNew optimization including the images that have been deactivated during the previous optimization.\n'); + active_images(desactivated_images) = ones(1,length(desactivated_images)); + desactivated_images = []; + + go_calib_optim_iter; + + if ~isempty(desactivated_images), + fprintf(1,['List of images left desactivated: ' num2str(desactivated_images) '\n' ] ); + end; + + param_list = [param_list_save(:,1:end-1) param_list]; + +end; + + +%%%%%%%%%%%%%%%%%%%% GRAPHICAL OUTPUT %%%%%%%%%%%%%%%%%%%%%%%% + +%graphout_calib; + diff --git a/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/go_calib_optim_iter.m b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/go_calib_optim_iter.m new file mode 100755 index 0000000..e3d22f6 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/go_calib_optim_iter.m @@ -0,0 +1,394 @@ +%go_calib_optim_iter +% +%Main calibration function. Computes the intrinsic andextrinsic parameters. +%Runs as a script. +% +%INPUT: x_1,x_2,x_3,...: Feature locations on the images +% X_1,X_2,X_3,...: Corresponding grid coordinates +% +%OUTPUT: fc: Camera focal length +% cc: Principal point coordinates +% kc: Distortion coefficients +% KK: The camera matrix (containing fc and cc) +% omc_1,omc_2,omc_3,...: 3D rotation vectors attached to the grid positions in space +% Tc_1,Tc_2,Tc_3,...: 3D translation vectors attached to the grid positions in space +% Rc_1,Rc_2,Rc_3,...: 3D rotation matrices corresponding to the omc vectors +% +%Method: Minimizes the pixel reprojection error in the least squares sense over the intrinsic +% camera parameters, and the extrinsic parameters (3D locations of the grids in space) +% +%Note: If the intrinsic camera parameters (fc, cc, kc) do not exist before, they are initialized through +% the function init_intrinsic_param.m. Otherwise, the variables in memory are used as initial guesses. +% +%Note: The row vector active_images consists of zeros and ones. To deactivate an image, set the +% corresponding entry in the active_images vector to zero. +% +%VERY IMPORTANT: This function works for 2D and 3D calibration rigs, except for init_intrinsic_param.m +%that is so far implemented to work only with 2D rigs. +%In the future, a more general function will be there. +%For now, if using a 3D calibration rig, quick_init is set to 1 for an easy initialization of the focal length + + +if ~exist('center_optim'), + center_optim = 1; %%% Set this variable to 0 if your do not want to estimate the principal point +end; + +if ~exist('est_dist'), + est_dist = [1;1;1;1]; +end; + +if ~exist('est_alpha'), + est_alpha = 0; % by default, do not estimate skew +end; + + +% Little fix in case of stupid values in the binary variables: +center_optim = ~~center_optim; +est_alpha = ~~est_alpha; +est_dist = ~~est_dist; + + +if ~exist('nx')&~exist('ny'), + fprintf(1,'WARNING: No image size (nx,ny) available. Setting nx=640 and ny=480\n'); + nx = 640; + ny = 480; +end; + + +check_active_images; + + +quick_init = 0; % Set to 1 for using a quick init (necessary when using 3D rigs) + + +if ~center_optim, % In the case where the principal point is not estimated, keep it at the center of the image + fprintf(1,'Principal point not optimized (center_optim=0). It is kept at the center of the image.\n'); + cc = [(nx-1)/2;(ny-1)/2]; +end; + + +if ~prod(est_dist), + fprintf(1,'\nDistortion not fully estimated. Check variable est_dist.\n'); +end; + +if ~est_alpha, + fprintf(1,'Skew not optimized (est_alpha=0).\n'); + alpha_c = 0; +end; + + +% Check 3D-ness of the calibration rig: +rig3D = 0; +for kk = ind_active, + eval(['X_kk = X_' num2str(kk) ';']); + if is3D(X_kk), + rig3D = 1; + end; +end; + +% If the rig is 3D, then no choice: the only valid initialization is manual! +if rig3D, + quick_init = 1; +end; + + + +alpha_smooth = 1; % set alpha_smooth = 1; for steepest gradient descent + + +% Conditioning threshold for view rejection +thresh_cond = 1e6; + + + +%% Initialization of the intrinsic parameters (if necessary) + +if ~exist('cc'), + fprintf(1,'Initialization of the principal point at the center of the image.\n'); + cc = [(nx-1)/2;(ny-1)/2]; + alpha_smooth = 0.4; % slow convergence +end; + + +if ~exist('kc'), + fprintf(1,'Initialization of the image distortion to zero.\n'); + kc = zeros(4,1); + alpha_smooth = 0.4; % slow convergence +end; + +if ~exist('alpha_c'), + fprintf(1,'Initialization of the image skew to zero.\n'); + alpha_c = 0; + alpha_smooth = 0.4; % slow convergence +end; + +if ~exist('fc')& quick_init, + FOV_angle = 35; % Initial camera field of view in degrees + fprintf(1,['Initialization of the focal length to a FOV of ' num2str(FOV_angle) ' degrees.\n']); + fc = (nx/2)/tan(pi*FOV_angle/360) * ones(2,1); + alpha_smooth = 0.4; % slow +end; + + +if ~exist('fc'), + % Initialization of the intrinsic parameters: + fprintf(1,'Initialization of the intrinsic parameters using the vanishing points of planar patterns.\n') + init_intrinsic_param; % The right way to go (if quick_init is not active)! + alpha_smooth = 0.4; % slow convergence +end; + + +if ~prod(est_dist), + % If no distortion estimated, set to zero the variables that are not estimated + kc = kc .* est_dist; +end; + + + + + +%% Initialization of the extrinsic parameters for global minimization: + + +init_param = [fc;cc;alpha_c;kc;zeros(6,1)]; + + + +for kk = 1:n_ima, + + if exist(['x_' num2str(kk)]), + + eval(['x_kk = x_' num2str(kk) ';']); + eval(['X_kk = X_' num2str(kk) ';']); + + if (isnan(x_kk(1,1))), + if active_images(kk), + fprintf(1,'Warning: Cannot calibrate with image %d. Need to extract grid corners first.\n',kk) + fprintf(1,' Set active_images(%d)=1; and run Extract grid corners.\n',kk) + end; + active_images(kk) = 0; + end; + if active_images(kk), + [omckk,Tckk] = compute_extrinsic_init(x_kk,X_kk,fc,cc,kc,alpha_c); + [omckk,Tckk,Rckk,JJ_kk] = compute_extrinsic_refine(omckk,Tckk,x_kk,X_kk,fc,cc,kc,alpha_c,20,thresh_cond); + if cond(JJ_kk)> thresh_cond, + active_images(kk) = 0; + omckk = NaN*ones(3,1); + Tckk = NaN*ones(3,1); + fprintf(1,'\nWarning: View #%d ill-conditioned. This image is now set inactive.\n',kk) + desactivated_images = [desactivated_images kk]; + end; + if isnan(omckk(1,1)), + %fprintf(1,'\nWarning: Desactivating image %d. Re-activate it later by typing:\nactive_images(%d)=1;\nand re-run optimization\n',[kk kk]) + active_images(kk) = 0; + end; + else + omckk = NaN*ones(3,1); + Tckk = NaN*ones(3,1); + end; + + else + + omckk = NaN*ones(3,1); + Tckk = NaN*ones(3,1); + + if active_images(kk), + fprintf(1,'Warning: Cannot calibrate with image %d. Need to extract grid corners first.\n',kk) + fprintf(1,' Set active_images(%d)=1; and run Extract grid corners.\n',kk) + end; + + active_images(kk) = 0; + + end; + + eval(['omc_' num2str(kk) ' = omckk;']); + eval(['Tc_' num2str(kk) ' = Tckk;']); + + init_param = [init_param; omckk ; Tckk]; + +end; + + +check_active_images; + + + +%-------------------- Main Optimization: + +fprintf(1,'\nMain calibration optimization procedure - Number of images: %d\n',length(ind_active)); + + +param = init_param; +change = 1; + +iter = 0; + +fprintf(1,'Gradient descent iterations: '); + +param_list = param; + +MaxIter = 30; + + +while (change > 1e-6)&(iter < MaxIter), + + fprintf(1,'%d...',iter+1); + + + %% The first step consists of updating the whole vector of knowns (intrinsic + extrinsic of active + %% images) through a one step steepest gradient descent. + + JJ = []; + ex = []; + + f = param(1:2); + c = param(3:4); + alpha = param(5); + k = param(6:9); + + + for kk = 1:n_ima, + + if active_images(kk), + + %omckk = param(4+6*(kk-1) + 3:6*kk + 3); + + %Tckk = param(6*kk+1 + 3:6*kk+3 + 3); + + omckk = param(15+6*(kk-1) + 1:15+6*(kk-1) + 3); + + Tckk = param(15+6*(kk-1) + 4:15+6*(kk-1) + 6); + + if isnan(omckk(1)), + fprintf(1,'Intrinsic parameters at frame %d do not exist\n',kk); + return; + end; + + eval(['X_kk = X_' num2str(kk) ';']); + eval(['x_kk = x_' num2str(kk) ';']); + + Np = size(X_kk,2); + + JJkk = zeros(2*Np,n_ima * 6 + 15); + + [x,dxdom,dxdT,dxdf,dxdc,dxdk,dxdalpha] = project_points2(X_kk,omckk,Tckk,f,c,k,alpha); + + exkk = x_kk - x; + + ex = [ex;exkk(:)]; + + JJkk(:,1:2) = dxdf; + JJkk(:,3:4) = dxdc; + JJkk(:,5) = dxdalpha; + JJkk(:,6:9) = dxdk; + JJkk(:,15+6*(kk-1) + 1:15+6*(kk-1) + 3) = dxdom; + JJkk(:,15+6*(kk-1) + 4:15+6*(kk-1) + 6) = dxdT; + + + + JJ = [JJ;JJkk]; + + + % Check if this view is ill-conditioned: + JJ_kk = [dxdom dxdT]; + if cond(JJ_kk)> thresh_cond, + active_images(kk) = 0; + fprintf(1,'\nWarning: View #%d ill-conditioned. This image is now set inactive.\n',kk) + desactivated_images = [desactivated_images kk]; + param(15+6*(kk-1) + 1:15+6*(kk-1) + 6) = NaN*ones(6,1); + end; + + + end; + + end; + + + % List of active images (necessary if changed): + check_active_images; + + + % The following vector helps to select the variables to update (for only active images): + + ind_Jac = find([ones(2,1);center_optim*ones(2,1);est_alpha;est_dist;zeros(6,1);reshape(ones(6,1)*active_images,6*n_ima,1)])'; + + + JJ = JJ(:,ind_Jac); + + JJ2 = JJ'*JJ; + + + % Smoothing coefficient: + + alpha_smooth2 = 1-(1-alpha_smooth)^(iter+1); %set to 1 to undo any smoothing! + + + param_innov = alpha_smooth2*inv(JJ2)*(JJ')*ex; + param_up = param(ind_Jac) + param_innov; + param(ind_Jac) = param_up; + + + % New intrinsic parameters: + + fc_current = param(1:2); + cc_current = param(3:4); + alpha_current = param(5); + kc_current = param(6:9); + + + % Change on the intrinsic parameters: + change = norm([fc_current;cc_current] - [f;c])/norm([fc_current;cc_current]); + + + %% Second step: (optional) - It makes convergence faster, and the region of convergence LARGER!!! + %% Recompute the extrinsic parameters only using compute_extrinsic.m (this may be useful sometimes) + %% The complete gradient descent method is useful to precisely update the intrinsic parameters. + + MaxIter2 = 20; + + + for kk = 1:n_ima, + if active_images(kk), + omc_current = param(15+6*(kk-1) + 1:15+6*(kk-1) + 3); + Tc_current = param(15+6*(kk-1) + 4:15+6*(kk-1) + 6); + eval(['X_kk = X_' num2str(kk) ';']); + eval(['x_kk = x_' num2str(kk) ';']); + [omc_current,Tc_current] = compute_extrinsic_init(x_kk,X_kk,fc_current,cc_current,kc_current,alpha_current); + [omckk,Tckk,Rckk,JJ_kk] = compute_extrinsic_refine(omc_current,Tc_current,x_kk,X_kk,fc_current,cc_current,kc_current,alpha_current,MaxIter2,thresh_cond); + if cond(JJ_kk)> thresh_cond, + active_images(kk) = 0; + fprintf(1,'\nWarning: View #%d ill-conditioned. This image is now set inactive.\n',kk) + desactivated_images = [desactivated_images kk]; + omckk = NaN*ones(3,1); + Tckk = NaN*ones(3,1); + end; + param(15+6*(kk-1) + 1:15+6*(kk-1) + 3) = omckk; + param(15+6*(kk-1) + 4:15+6*(kk-1) + 6) = Tckk; + end; + end; + + param_list = [param_list param]; + + iter = iter + 1; + +end; + +fprintf(1,'\n'); + + +solution = param; + + +%%% Extraction of the final intrinsic and extrinsic paramaters: + +extract_parameters; + +comp_error_calib; + +fprintf(1,'\n\nCalibration results after optimization:\n\n'); +fprintf(1,'Focal Length: fc = [ %3.5f %3.5f ]\n',fc); +fprintf(1,'Principal point: cc = [ %3.5f %3.5f ]\n',cc); +fprintf(1,'Skew: alpha_c = [ %3.5f ] => angle of pixel = %3.5f degrees\n',alpha_c,90 - atan(alpha_c)*180/pi); +fprintf(1,'Distortion: kc = [ %3.5f %3.5f %3.5f %3.5f ]\n',kc); +fprintf(1,'Pixel error: err = [ %3.5f %3.5f ]\n\n',err_std); + diff --git a/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/ima_read_calib.m b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/ima_read_calib.m new file mode 100755 index 0000000..dbbc4e0 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/ima_read_calib.m @@ -0,0 +1,158 @@ + +if ~exist('calib_name')|~exist('format_image'), + data_calib; + return; +end; + +check_directory; + +if ~exist('n_ima'), + data_calib; + return; +end; + +check_active_images; + + +images_read = active_images; + + +if exist('image_numbers'), + first_num = image_numbers(1); +end; + + +% Just to fix a minor bug: +if ~exist('first_num'), + first_num = image_numbers(1); +end; + + +image_numbers = first_num:n_ima-1+first_num; + +no_image_file = 0; + +i = 1; + +while (i <= n_ima), % & (~no_image_file), + + if active_images(i), + + %fprintf(1,'Loading image %d...\n',i); + + if ~type_numbering, + number_ext = num2str(image_numbers(i)); + else + number_ext = sprintf(['%.' num2str(N_slots) 'd'],image_numbers(i)); + end; + + ima_name = [calib_name number_ext '.' format_image]; + + if i == ind_active(1), + fprintf(1,'Loading image '); + end; + + if exist(ima_name), + + fprintf(1,'%d...',i); + + if format_image(1) == 'p', + if format_image(2) == 'p', + Ii = double(loadppm(ima_name)); + else + Ii = double(loadpgm(ima_name)); + end; + else + if format_image(1) == 'r', + Ii = readras(ima_name); + else + Ii = double(imread(ima_name)); + end; + end; + + + if size(Ii,3)>1, + Ii = Ii(:,:,2); + end; + + eval(['I_' num2str(i) ' = Ii;']); + + else + + fprintf(1,'%d...no image...',i); + + images_read(i) = 0; + + %no_image_file = 1; + + end; + + end; + + i = i+1; + +end; + + +ind_read = find(images_read); + + + + +if isempty(ind_read), + + fprintf(1,'\nWARNING! No image were read\n'); + + no_image_file = 1; + + +else + + + %fprintf(1,'\nWARNING! Every exsisting image in the directory is set active.\n'); + + + if no_image_file, + + %fprintf(1,'WARNING! Some images were not read properly\n'); + + end; + + + fprintf(1,'\n'); + + if size(I_1,1)~=480, + small_calib_image = 1; + else + small_calib_image = 0; + end; + + [Hcal,Wcal] = size(I_1); % size of the calibration image + + [ny,nx] = size(I_1); + + clickname = []; + + map = gray(256); + + %string_save = 'save calib_data n_ima type_numbering N_slots image_numbers format_image calib_name Hcal Wcal nx ny map small_calib_image'; + + %eval(string_save); + + disp('done'); + %click_calib; + +end; + +if ~exist('map'), map = gray(256); end; + +active_images = images_read; + +% Show all the calibration images: + + +if ~isempty(ind_read), + + mosaic; + +end; diff --git a/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/init_intrinsic_param.m b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/init_intrinsic_param.m new file mode 100755 index 0000000..94a5240 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/init_intrinsic_param.m @@ -0,0 +1,158 @@ +%init_intrinsic_param +% +%Initialization of the intrinsic parameters. +%Runs as a script. +% +%INPUT: x_1,x_2,x_3,...: Feature locations on the images +% X_1,X_2,X_3,...: Corresponding grid coordinates +% +%OUTPUT: fc: Camera focal length +% cc: Principal point coordinates +% kc: Distortion coefficients +% alpha_c: skew coefficient +% KK: The camera matrix (containing fc, cc and alpha_c) +% +%Method: Computes the planar homographies H_1, H_2, H_3, ... and computes +% the focal length fc from orthogonal vanishing points constraint. +% The principal point cc is assumed at the center of the image. +% Assumes no image distortion (kc = [0;0;0;0]) +% +%Note: The row vector active_images consists of zeros and ones. To deactivate an image, set the +% corresponding entry in the active_images vector to zero. +% +% +%Important function called within that program: +% +%compute_homography.m: Computes the planar homography between points on the grid in 3D, and the image plane. +% +% +%VERY IMPORTANT: This function works only with 2D rigs. +%In the future, a more general function will be there (working with 3D rigs as well). + + + +check_active_images; + +if ~exist(['x_' num2str(ind_active(1)) ]), + click_calib; +end; + + +fprintf(1,'\nInitialization of the intrinsic parameters - Number of images: %d\n',length(ind_active)); + + +% Initialize the homographies: + +for kk = 1:n_ima, + eval(['x_kk = x_' num2str(kk) ';']); + eval(['X_kk = X_' num2str(kk) ';']); + if (isnan(x_kk(1,1))), + if active_images(kk), + fprintf(1,'WARNING: Cannot calibrate with image %d. Need to extract grid corners first.\n',kk) + fprintf(1,' Set active_images(%d)=1; and run Extract grid corners.\n',kk) + end; + active_images(kk) = 0; + end; + if active_images(kk), + eval(['H_' num2str(kk) ' = compute_homography(x_kk,X_kk(1:2,:));']); + else + eval(['H_' num2str(kk) ' = NaN*ones(3,3);']); + end; +end; + +check_active_images; + +% initial guess for principal point and distortion: + +if ~exist('nx'), [ny,nx] = size(I); end; + +c_init = [nx;ny]/2 - 0.5; % initialize at the center of the image +k_init = [0;0;0;0]; % initialize to zero (no distortion) + + + +% Compute explicitely the focal length using all the (mutually orthogonal) vanishing points +% note: The vanihing points are hidden in the planar collineations H_kk + +A = []; +b = []; + +% matrix that subtract the principal point: +Sub_cc = [1 0 -c_init(1);0 1 -c_init(2);0 0 1]; + +for kk=1:n_ima, + + if active_images(kk), + + eval(['Hkk = H_' num2str(kk) ';']); + + Hkk = Sub_cc * Hkk; + + % Extract vanishing points (direct and diagonals): + + V_hori_pix = Hkk(:,1); + V_vert_pix = Hkk(:,2); + V_diag1_pix = (Hkk(:,1)+Hkk(:,2))/2; + V_diag2_pix = (Hkk(:,1)-Hkk(:,2))/2; + + V_hori_pix = V_hori_pix/norm(V_hori_pix); + V_vert_pix = V_vert_pix/norm(V_vert_pix); + V_diag1_pix = V_diag1_pix/norm(V_diag1_pix); + V_diag2_pix = V_diag2_pix/norm(V_diag2_pix); + + a1 = V_hori_pix(1); + b1 = V_hori_pix(2); + c1 = V_hori_pix(3); + + a2 = V_vert_pix(1); + b2 = V_vert_pix(2); + c2 = V_vert_pix(3); + + a3 = V_diag1_pix(1); + b3 = V_diag1_pix(2); + c3 = V_diag1_pix(3); + + a4 = V_diag2_pix(1); + b4 = V_diag2_pix(2); + c4 = V_diag2_pix(3); + + A_kk = [a1*a2 b1*b2; + a3*a4 b3*b4]; + + b_kk = -[c1*c2;c3*c4]; + + + A = [A;A_kk]; + b = [b;b_kk]; + + end; + +end; + + +% use all the vanishing points to estimate focal length: + +f_init = sqrt(abs(1./(inv(A'*A)*A'*b))); % if using a two-focal model for initial guess + +alpha_init = 0; + +%f_init = sqrt(b'*(sum(A')') / (b'*b)) * ones(2,1); % if single focal length model is used + + +% Global calibration matrix (initial guess): + +KK = [f_init(1) alpha_init*f_init(1) c_init(1);0 f_init(2) c_init(2); 0 0 1]; +inv_KK = inv(KK); + + +cc = c_init; +fc = f_init; +kc = k_init; +alpha_c = alpha_init; + + +fprintf(1,'\n\nCalibration parameters after initialization:\n\n'); +fprintf(1,'Focal Length: fc = [ %3.5f %3.5f ]\n',fc); +fprintf(1,'Principal point: cc = [ %3.5f %3.5f ]\n',cc); +fprintf(1,'Skew: alpha_c = [ %3.5f ] => angle of pixel = %3.5f degrees\n',alpha_c,90 - atan(alpha_c)*180/pi); +fprintf(1,'Distortion: kc = [ %3.5f %3.5f %3.5f %3.5f ]\n',kc); diff --git a/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/is3D.m b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/is3D.m new file mode 100755 index 0000000..ab00b3d --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/is3D.m @@ -0,0 +1,19 @@ +function test = is3D(X), + + +Np = size(X,2); + +%% Check for planarity of the structure: + +X_mean = mean(X')'; + +Y = X - (X_mean*ones(1,Np)); + +YY = Y*Y'; + +[U,S,V] = svd(YY); + +r = S(3,3)/S(2,2); + +test = (r > 1e-3); + diff --git a/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/loading_calib.m b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/loading_calib.m new file mode 100755 index 0000000..a0f50d2 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/loading_calib.m @@ -0,0 +1,10 @@ +if ~exist('Calib_Results.mat'), + fprintf(1,'\nCalibration file Calib_Results.mat not found!\n'); + return; +end; + +fprintf(1,'\nLoading calibration results from Calib_Results.mat\n'); + +load Calib_Results + +fprintf(1,'done\n'); diff --git a/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/loadinr.m b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/loadinr.m new file mode 100755 index 0000000..91b6f89 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/loadinr.m @@ -0,0 +1,52 @@ +%LOADINR Load an INRIMAGE format file +% +% LOADINR(filename, im) +% +% Load an INRIA image format file and return it as a matrix +% +% SEE ALSO: saveinr +% +% Copyright (c) Peter Corke, 1999 Machine Vision Toolbox for Matlab + + +% Peter Corke 1996 + +function im = loadinr(fname, im) + + fid = fopen(fname, 'r'); + + s = fgets(fid); + if strcmp(s(1:12), '#INRIMAGE-4#') == 0, + error('not INRIMAGE format'); + end + + % not very complete, only looks for the X/YDIM keys + while 1, + s = fgets(fid); + n = length(s) - 1; + if s(1) == '#', + break + end + if strcmp(s(1:5), 'XDIM='), + cols = str2num(s(6:n)); + end + if strcmp(s(1:5), 'YDIM='), + rows = str2num(s(6:n)); + end + if strcmp(s(1:4), 'CPU='), + if strcmp(s(5:n), 'sun') == 0, + error('not sun data ordering'); + end + end + + end + disp(['INRIMAGE format file ' num2str(rows) ' x ' num2str(cols)]) + + % now the binary data + fseek(fid, 256, 'bof'); + [im count] = fread(fid, [cols rows], 'float32'); + im = im'; + if count ~= (rows*cols), + error('file too short'); + end + fclose(fid); diff --git a/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/loadpgm.m b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/loadpgm.m new file mode 100755 index 0000000..dfa8b61 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/loadpgm.m @@ -0,0 +1,89 @@ +%LOADPGM Load a PGM image +% +% I = loadpgm(filename) +% +% Returns a matrix containing the image loaded from the PGM format +% file filename. Handles ASCII (P2) and binary (P5) PGM file formats. +% +% If the filename has no extension, and open fails, a '.pgm' will +% be appended. +% +% +% Copyright (c) Peter Corke, 1999 Machine Vision Toolbox for Matlab + + +% Peter Corke 1994 + +function I = loadpgm(file) + white = [' ' 9 10 13]; % space, tab, lf, cr + white = setstr(white); + + fid = fopen(file, 'r'); + if fid < 0, + fid = fopen([file '.pgm'], 'r'); + end + if fid < 0, + error('Couldn''t open file'); + end + + magic = fread(fid, 2, 'char'); + while 1 + c = fread(fid,1,'char'); + if c == '#', + fgetl(fid); + elseif ~any(c == white) + fseek(fid, -1, 'cof'); % unputc() + break; + end + end + cols = fscanf(fid, '%d', 1); + while 1 + c = fread(fid,1,'char'); + if c == '#', + fgetl(fid); + elseif ~any(c == white) + fseek(fid, -1, 'cof'); % unputc() + break; + end + end + rows = fscanf(fid, '%d', 1); + while 1 + c = fread(fid,1,'char'); + if c == '#', + fgetl(fid); + elseif ~any(c == white) + fseek(fid, -1, 'cof'); % unputc() + break; + end + end + maxval = fscanf(fid, '%d', 1); + while 1 + c = fread(fid,1,'char'); + if c == '#', + fgetl(fid); + elseif ~any(c == white) + fseek(fid, -1, 'cof'); % unputc() + break; + end + end + if magic(1) == 'P', + if magic(2) == '2', + %disp(['ASCII PGM file ' num2str(rows) ' x ' num2str(cols)]) + I = fscanf(fid, '%d', [cols rows])'; + elseif magic(2) == '5', + %disp(['Binary PGM file ' num2str(rows) ' x ' num2str(cols)]) + if maxval == 1, + fmt = 'unint1'; + elseif maxval == 15, + fmt = 'uint4'; + elseif maxval == 255, + fmt = 'uint8'; + elseif maxval == 2^32-1, + fmt = 'uint32'; + end + I = fread(fid, [cols rows], fmt)'; + else + disp('Not a PGM file'); + end + end + fclose(fid); diff --git a/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/loadppm.m b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/loadppm.m new file mode 100755 index 0000000..0c004fc --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/loadppm.m @@ -0,0 +1,109 @@ +%LOADPPM Load a PPM image +% +% I = loadppm(filename) +% +% Returns a matrix containing the image loaded from the PPM format +% file filename. Handles ASCII (P3) and binary (P6) PPM file formats. +% +% If the filename has no extension, and open fails, a '.ppm' and +% '.pnm' extension will be tried. +% +% SEE ALSO: saveppm loadpgm +% +% Copyright (c) Peter Corke, 1999 Machine Vision Toolbox for Matlab + + +% Peter Corke 1994 + +function I = loadppm(file) + white = [' ' 9 10 13]; % space, tab, lf, cr + white = setstr(white); + + fid = fopen(file, 'r'); + if fid < 0, + fid = fopen([file '.ppm'], 'r'); + end + if fid < 0, + fid = fopen([file '.pnm'], 'r'); + end + if fid < 0, + error('Couldn''t open file'); + end + + magic = fread(fid, 2, 'char'); + while 1 + c = fread(fid,1,'char'); + if c == '#', + fgetl(fid); + elseif ~any(c == white) + fseek(fid, -1, 'cof'); % unputc() + break; + end + end + cols = fscanf(fid, '%d', 1); + while 1 + c = fread(fid,1,'char'); + if c == '#', + fgetl(fid); + elseif ~any(c == white) + fseek(fid, -1, 'cof'); % unputc() + break; + end + end + rows = fscanf(fid, '%d', 1); + while 1 + c = fread(fid,1,'char'); + if c == '#', + fgetl(fid); + elseif ~any(c == white) + fseek(fid, -1, 'cof'); % unputc() + break; + end + end + maxval = fscanf(fid, '%d', 1); + while 1 + c = fread(fid,1,'char'); + if c == '#', + fgetl(fid); + elseif ~any(c == white) + fseek(fid, -1, 'cof'); % unputc() + break; + end + end + if magic(1) == 'P', + if magic(2) == '3', + %disp(['ASCII PPM file ' num2str(rows) ' x ' num2str(cols)]) + I = fscanf(fid, '%d', [cols*3 rows]); + elseif magic(2) == '6', + %disp(['Binary PPM file ' num2str(rows) ' x ' num2str(cols)]) + if maxval == 1, + fmt = 'unint1'; + elseif maxval == 15, + fmt = 'uint4'; + elseif maxval == 255, + fmt = 'uint8'; + elseif maxval == 2^32-1, + fmt = 'uint32'; + end + I = fread(fid, [cols*3 rows], fmt); + else + disp('Not a PPM file'); + end + end + % + % now the matrix has interleaved columns of R, G, B + % + I = I'; + size(I); + R = I(:,1:3:(cols*3)); + G = I(:,2:3:(cols*3)); + B = I(:,3:3:(cols*3)); + fclose(fid); + + + I = zeros(rows,cols,3); + I(:,:,1) = R; + I(:,:,2) = G; + I(:,:,3) = B; + I = uint8(I); + \ No newline at end of file diff --git a/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/mean_std_robust.m b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/mean_std_robust.m new file mode 100755 index 0000000..0d18a62 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/mean_std_robust.m @@ -0,0 +1,7 @@ +function [m,s] = mean_std_robust(x); + +x = x(:); + +m = median(x); + +s = median(abs(x - m))*1.4836; diff --git a/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/mosaic.m b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/mosaic.m new file mode 100755 index 0000000..b056661 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/mosaic.m @@ -0,0 +1,92 @@ + +if ~exist('I_1'), + active_images_save = active_images; + ima_read_calib; + active_images = active_images_save; + check_active_images; +end; + +check_active_images; + +if isempty(ind_read), + return; +end; + + +n_col = floor(sqrt(n_ima*nx/ny)); + +n_row = ceil(n_ima / n_col); + + +ker2 = 1; +for ii = 1:n_col, + ker2 = conv(ker2,[1/4 1/2 1/4]); +end; + + +II = I_1(1:n_col:end,1:n_col:end); + +[ny2,nx2] = size(II); + + + +kk_c = 1; + +II_mosaic = []; + +for jj = 1:n_row, + + + II_row = []; + + for ii = 1:n_col, + + if (exist(['I_' num2str(kk_c)])) & (kk_c <= n_ima), + + if active_images(kk_c), + eval(['I = I_' num2str(kk_c) ';']); + %I = conv2(conv2(I,ker2,'same'),ker2','same'); % anti-aliasing + I = I(1:n_col:end,1:n_col:end); + else + I = zeros(ny2,nx2); + end; + + else + + I = zeros(ny2,nx2); + + end; + + + + II_row = [II_row I]; + + if ii ~= n_col, + + II_row = [II_row zeros(ny2,3)]; + + end; + + + kk_c = kk_c + 1; + + end; + + nn2 = size(II_row,2); + + if jj ~= n_row, + II_row = [II_row; zeros(3,nn2)]; + end; + + II_mosaic = [II_mosaic ; II_row]; + +end; + +figure(2); +image(II_mosaic); +colormap(gray(256)); +title('Calibration images'); +set(gca,'Xtick',[]) +set(gca,'Ytick',[]) +axis('image'); + diff --git a/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/normalize.m b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/normalize.m new file mode 100755 index 0000000..6dc7149 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/normalize.m @@ -0,0 +1,43 @@ +function [xn] = normalize(x_kk,fc,cc,kc,alpha_c), + +%normalize +% +%[xn] = normalize(x_kk,fc,cc,kc,alpha_c) +% +%Computes the normalized coordinates xn given the pixel coordinates x_kk +%and the intrinsic camera parameters fc, cc and kc. +% +%INPUT: x_kk: Feature locations on the images +% fc: Camera focal length +% cc: Principal point coordinates +% kc: Distortion coefficients +% alpha_c: Skew coefficient +% +%OUTPUT: xn: Normalized feature locations on the image plane (a 2XN matrix) +% +%Important functions called within that program: +% +%comp_distortion_oulu: undistort pixel coordinates. + +if nargin < 5, + alpha_c = 0; + if nargin < 4; + kc = [0;0;0;0]; + if nargin < 3; + cc = [0;0]; + if nargin < 2, + fc = [1;1]; + end; + end; + end; +end; + + +% First subtract principal point, and divide by the focal length: +temp = (x_kk(2,:) - cc(2))/fc(2); +x_distort = [(x_kk(1,:) - cc(1))/fc(1) - alpha_c*temp;temp]; + + +%Compensate for lens distortion: + +xn = comp_distortion_oulu(x_distort,kc); diff --git a/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/pgmread.m b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/pgmread.m new file mode 100755 index 0000000..c96ccb7 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/pgmread.m @@ -0,0 +1,26 @@ +function img = pgmread(filename) +% function img = pgmread(filename) +% this is my version of pgmread for the pgm file created by XV. +% +% this program also corrects for the shifts in the image from pm file. + +fid = fopen(filename,'r'); +fscanf(fid, 'P5\n'); +cmt = '#'; +while findstr(cmt, '#'), + cmt = fgets(fid); + if length(findstr(cmt, '#')) ~= 1, + YX = sscanf(cmt, '%d %d'); + y = YX(1); x = YX(2); + end +end + +%fgets(fid); + +%img = fscanf(fid,'%d',size); +%img = img'; + +img = fread(fid,[y,x],'uint8'); +img = img'; +fclose(fid); + diff --git a/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/project2_oulu.m b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/project2_oulu.m new file mode 100755 index 0000000..c5c4a34 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/project2_oulu.m @@ -0,0 +1,53 @@ +function [x] = project2_oulu(X,R,T,f,t,k) +%PROJECT Subsidiary to calib + +% (c) Pietro Perona -- March 24, 1994 +% California Institute of Technology +% Pasadena, CA +% +% Renamed because project exists in matlab 5.2!!! +% Now uses the more elaborate intrinsic model from Oulu + + + +[m,n] = size(X); + +Y = R*X + T*ones(1,n); +Z = Y(3,:); + +f = f(:); %% make a column vector +if length(f)==1, + f = [f f]'; +end; + +x = (Y(1:2,:) ./ (ones(2,1) * Z)) ; + + +radius_2 = x(1,:).^2 + x(2,:).^2; + +if length(k) > 1, + + radial_distortion = 1 + ones(2,1) * ((k(1) * radius_2) + (k(2) * radius_2.^2)); + + if length(k) < 4, + + delta_x = zeros(2,n); + + else + + delta_x = [2*k(3)*x(1,:).*x(2,:) + k(4)*(radius_2 + 2*x(1,:).^2) ; + k(3) * (radius_2 + 2*x(2,:).^2)+2*k(4)*x(1,:).*x(2,:)]; + + end; + + +else + + radial_distortion = 1 + ones(2,1) * ((k(1) * radius_2)); + + delta_x = zeros(2,n); + +end; + + +x = (x .* radial_distortion + delta_x).* (f * ones(1,n)) + t*ones(1,n); diff --git a/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/project_points.m b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/project_points.m new file mode 100755 index 0000000..1823490 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/project_points.m @@ -0,0 +1,276 @@ +function [xp,dxpdom,dxpdT,dxpdf,dxpdc,dxpdk] = project_points(X,om,T,f,c,k) + +%project_points.m +% +%[xp,dxpdom,dxpdT,dxpdf,dxpdc,dxpdk] = project_points(X,om,T,f,c,k) +% +%Projects a 3D structure onto the image plane. +% +%INPUT: X: 3D structure in the world coordinate frame (3xN matrix for N points) +% (om,T): Rigid motion parameters between world coordinate frame and camera reference frame +% om: rotation vector (3x1 vector); T: translation vector (3x1 vector) +% f: camera focal length in units of horizontal and vertical pixel units (2x1 vector) +% c: principal point location in pixel units (2x1 vector) +% k: Distortion coefficients (radial and tangential) (4x1 vector) +% +%OUTPUT: xp: Projected pixel coordinates (2xN matrix for N points) +% dxpdom: Derivative of xp with respect to om ((2N)x3 matrix) +% dxpdT: Derivative of xp with respect to T ((2N)x3 matrix) +% dxpdf: Derivative of xp with respect to f ((2N)x2 matrix) +% dxpdc: Derivative of xp with respect to c ((2N)x2 matrix) +% dxpdk: Derivative of xp with respect to k ((2N)x4 matrix) +% +%Definitions: +%Let P be a point in 3D of coordinates X in the world reference frame (stored in the matrix X) +%The coordinate vector of P in the camera reference frame is: Xc = R*X + T +%where R is the rotation matrix corresponding to the rotation vector om: R = rodrigues(om); +%call x, y and z the 3 coordinates of Xc: x = Xc(1); y = Xc(2); z = Xc(3); +%The pinehole projection coordinates of P is [a;b] where a=x/z and b=y/z. +%call r^2 = a^2 + b^2. +%The distorted point coordinates are: xd = [xx;yy] where: +% +%xx = a * (1 + kc(1)*r^2 + kc(2)*r^4) + 2*kc(3)*a*b + kc(4)*(r^2 + 2*a^2); +%yy = b * (1 + kc(1)*r^2 + kc(2)*r^4) + kc(3)*(r^2 + 2*b^2) + 2*kc(4)*a*b; +% +%The left terms correspond to radial distortion, the right terms correspond to tangential distortion +% +%Fianlly, convertion into pixel coordinates: The final pixel coordinates vector xp=[xxp;yyp] where: +% +%xxp = f(1)*xx + c(1) +%yyp = f(2)*yy + c(2) +% +% +%NOTE: About 90 percent of the code takes care fo computing the Jacobian matrices +% +% +%Important function called within that program: +% +%rodrigues.m: Computes the rotation matrix corresponding to a rotation vector +% +%rigid_motion.m: Computes the rigid motion transformation of a given structure + + + +if nargin < 6, + k = zeros(4,1); + if nargin < 5, + c = zeros(2,1); + if nargin < 4, + f = ones(2,1); + if nargin < 3, + T = zeros(3,1); + if nargin < 2, + om = zeros(3,1); + if nargin < 1, + error('Need at least a 3D structure to project (in project_points.m)'); + return; + end; + end; + end; + end; + end; +end; + + +[m,n] = size(X); + +[Y,dYdom,dYdT] = rigid_motion(X,om,T); + + +inv_Z = 1./Y(3,:); + +x = (Y(1:2,:) .* (ones(2,1) * inv_Z)) ; + + +bb = (-x(1,:) .* inv_Z)'*ones(1,3); +cc = (-x(2,:) .* inv_Z)'*ones(1,3); + + +dxdom = zeros(2*n,3); +dxdom(1:2:end,:) = ((inv_Z')*ones(1,3)) .* dYdom(1:3:end,:) + bb .* dYdom(3:3:end,:); +dxdom(2:2:end,:) = ((inv_Z')*ones(1,3)) .* dYdom(2:3:end,:) + cc .* dYdom(3:3:end,:); + +dxdT = zeros(2*n,3); +dxdT(1:2:end,:) = ((inv_Z')*ones(1,3)) .* dYdT(1:3:end,:) + bb .* dYdT(3:3:end,:); +dxdT(2:2:end,:) = ((inv_Z')*ones(1,3)) .* dYdT(2:3:end,:) + cc .* dYdT(3:3:end,:); + + +% Add distortion: + +r2 = x(1,:).^2 + x(2,:).^2; + + + +dr2dom = 2*((x(1,:)')*ones(1,3)) .* dxdom(1:2:end,:) + 2*((x(2,:)')*ones(1,3)) .* dxdom(2:2:end,:); +dr2dT = 2*((x(1,:)')*ones(1,3)) .* dxdT(1:2:end,:) + 2*((x(2,:)')*ones(1,3)) .* dxdT(2:2:end,:); + + +r4 = r2.^2; + +dr4dom = 2*((r2')*ones(1,3)) .* dr2dom; +dr4dT = 2*((r2')*ones(1,3)) .* dr2dT; + + +% Radial distortion: + +cdist = 1 + k(1) * r2 + k(2) * r4; + +dcdistdom = k(1) * dr2dom + k(2) * dr4dom; +dcdistdT = k(1) * dr2dT+ k(2) * dr4dT; +dcdistdk = [ r2' r4' zeros(n,2)]; + + +xd1 = x .* (ones(2,1)*cdist); + +dxd1dom = zeros(2*n,3); +dxd1dom(1:2:end,:) = (x(1,:)'*ones(1,3)) .* dcdistdom; +dxd1dom(2:2:end,:) = (x(2,:)'*ones(1,3)) .* dcdistdom; +coeff = (reshape([cdist;cdist],2*n,1)*ones(1,3)); +dxd1dom = dxd1dom + coeff.* dxdom; + +dxd1dT = zeros(2*n,3); +dxd1dT(1:2:end,:) = (x(1,:)'*ones(1,3)) .* dcdistdT; +dxd1dT(2:2:end,:) = (x(2,:)'*ones(1,3)) .* dcdistdT; +dxd1dT = dxd1dT + coeff.* dxdT; + +dxd1dk = zeros(2*n,4); +dxd1dk(1:2:end,:) = (x(1,:)'*ones(1,4)) .* dcdistdk; +dxd1dk(2:2:end,:) = (x(2,:)'*ones(1,4)) .* dcdistdk; + + + +% tangential distortion: + +a1 = 2.*x(1,:).*x(2,:); +a2 = r2 + 2*x(1,:).^2; +a3 = r2 + 2*x(2,:).^2; + +delta_x = [k(3)*a1 + k(4)*a2 ; + k(3) * a3 + k(4)*a1]; + + +ddelta_xdx = zeros(2*n,2*n); +aa = (2*k(3)*x(2,:)+6*k(4)*x(1,:))'*ones(1,3); +bb = (2*k(3)*x(1,:)+2*k(4)*x(2,:))'*ones(1,3); +cc = (6*k(3)*x(2,:)+2*k(4)*x(1,:))'*ones(1,3); + +ddelta_xdom = zeros(2*n,3); +ddelta_xdom(1:2:end,:) = aa .* dxdom(1:2:end,:) + bb .* dxdom(2:2:end,:); +ddelta_xdom(2:2:end,:) = bb .* dxdom(1:2:end,:) + cc .* dxdom(2:2:end,:); + +ddelta_xdT = zeros(2*n,3); +ddelta_xdT(1:2:end,:) = aa .* dxdT(1:2:end,:) + bb .* dxdT(2:2:end,:); +ddelta_xdT(2:2:end,:) = bb .* dxdT(1:2:end,:) + cc .* dxdT(2:2:end,:); + +ddelta_xdk = zeros(2*n,4); +ddelta_xdk(1:2:end,3) = a1'; +ddelta_xdk(1:2:end,4) = a2'; +ddelta_xdk(2:2:end,3) = a3'; +ddelta_xdk(2:2:end,4) = a1'; + + + +xd2 = xd1 + delta_x; + +dxd2dom = dxd1dom + ddelta_xdom ; +dxd2dT = dxd1dT + ddelta_xdT; +dxd2dk = dxd1dk + ddelta_xdk ; + + +% Pixel coordinates: + +xp = xd2 .* (f * ones(1,n)) + c*ones(1,n); + +coeff = reshape(f*ones(1,n),2*n,1); + +dxpdom = (coeff*ones(1,3)) .* dxd2dom; +dxpdT = (coeff*ones(1,3)) .* dxd2dT; +dxpdk = (coeff*ones(1,4)) .* dxd2dk; + +dxpdf = zeros(2*n,2); +dxpdf(1:2:end,1) = xd2(1,:)'; +dxpdf(2:2:end,2) = xd2(2,:)'; + +dxpdc = zeros(2*n,2); +dxpdc(1:2:end,1) = ones(n,1); +dxpdc(2:2:end,2) = ones(n,1); + + +return; + +% Test of the Jacobians: + +n = 10; + +X = 10*randn(3,n); +om = randn(3,1); +T = [10*randn(2,1);40]; +f = 1000*rand(2,1); +c = 1000*randn(2,1); +k = 0.5*randn(4,1); + + +[x,dxdom,dxdT,dxdf,dxdc,dxdk] = project_points(X,om,T,f,c,k); + + +% Test on om: NOT OK + +dom = 0.000000001 * norm(om)*randn(3,1); +om2 = om + dom; + +[x2] = project_points(X,om2,T,f,c,k); + +x_pred = x + reshape(dxdom * dom,2,n); + + +norm(x2-x)/norm(x2 - x_pred) + + +% Test on T: OK!! + +dT = 0.0001 * norm(T)*randn(3,1); +T2 = T + dT; + +[x2] = project_points(X,om,T2,f,c,k); + +x_pred = x + reshape(dxdT * dT,2,n); + + +norm(x2-x)/norm(x2 - x_pred) + + + +% Test on f: OK!! + +df = 0.001 * norm(f)*randn(2,1); +f2 = f + df; + +[x2] = project_points(X,om,T,f2,c,k); + +x_pred = x + reshape(dxdf * df,2,n); + + +norm(x2-x)/norm(x2 - x_pred) + + +% Test on c: OK!! + +dc = 0.01 * norm(c)*randn(2,1); +c2 = c + dc; + +[x2] = project_points(X,om,T,f,c2,k); + +x_pred = x + reshape(dxdc * dc,2,n); + +norm(x2-x)/norm(x2 - x_pred) + +% Test on k: OK!! + +dk = 0.001 * norm(4)*randn(4,1); +k2 = k + dk; + +[x2] = project_points(X,om,T,f,c,k2); + +x_pred = x + reshape(dxdk * dk,2,n); + +norm(x2-x)/norm(x2 - x_pred) diff --git a/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/project_points2.m b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/project_points2.m new file mode 100755 index 0000000..5bb1b91 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/project_points2.m @@ -0,0 +1,312 @@ +function [xp,dxpdom,dxpdT,dxpdf,dxpdc,dxpdk,dxpdalpha] = project_points2(X,om,T,f,c,k,alpha) + +%project_points.m +% +%[xp,dxpdom,dxpdT,dxpdf,dxpdc,dxpdk] = project_points2(X,om,T,f,c,k,alpha) +% +%Projects a 3D structure onto the image plane. +% +%INPUT: X: 3D structure in the world coordinate frame (3xN matrix for N points) +% (om,T): Rigid motion parameters between world coordinate frame and camera reference frame +% om: rotation vector (3x1 vector); T: translation vector (3x1 vector) +% f: camera focal length in units of horizontal and vertical pixel units (2x1 vector) +% c: principal point location in pixel units (2x1 vector) +% k: Distortion coefficients (radial and tangential) (4x1 vector) +% alpha: Skew coefficient between x and y pixel (alpha = 0 <=> square pixels) +% +%OUTPUT: xp: Projected pixel coordinates (2xN matrix for N points) +% dxpdom: Derivative of xp with respect to om ((2N)x3 matrix) +% dxpdT: Derivative of xp with respect to T ((2N)x3 matrix) +% dxpdf: Derivative of xp with respect to f ((2N)x2 matrix) +% dxpdc: Derivative of xp with respect to c ((2N)x2 matrix) +% dxpdk: Derivative of xp with respect to k ((2N)x4 matrix) +% +%Definitions: +%Let P be a point in 3D of coordinates X in the world reference frame (stored in the matrix X) +%The coordinate vector of P in the camera reference frame is: Xc = R*X + T +%where R is the rotation matrix corresponding to the rotation vector om: R = rodrigues(om); +%call x, y and z the 3 coordinates of Xc: x = Xc(1); y = Xc(2); z = Xc(3); +%The pinehole projection coordinates of P is [a;b] where a=x/z and b=y/z. +%call r^2 = a^2 + b^2. +%The distorted point coordinates are: xd = [xx;yy] where: +% +%xx = a * (1 + kc(1)*r^2 + kc(2)*r^4) + 2*kc(3)*a*b + kc(4)*(r^2 + 2*a^2); +%yy = b * (1 + kc(1)*r^2 + kc(2)*r^4) + kc(3)*(r^2 + 2*b^2) + 2*kc(4)*a*b; +% +%The left terms correspond to radial distortion, the right terms correspond to tangential distortion +% +%Finally, convertion into pixel coordinates: The final pixel coordinates vector xp=[xxp;yyp] where: +% +%xxp = f(1)*(xx + alpha*yy) + c(1) +%yyp = f(2)*yy + c(2) +% +% +%NOTE: About 90 percent of the code takes care fo computing the Jacobian matrices +% +% +%Important function called within that program: +% +%rodrigues.m: Computes the rotation matrix corresponding to a rotation vector +% +%rigid_motion.m: Computes the rigid motion transformation of a given structure + + +if nargin < 7, + alpha = 0; + if nargin < 6, + k = zeros(4,1); + if nargin < 5, + c = zeros(2,1); + if nargin < 4, + f = ones(2,1); + if nargin < 3, + T = zeros(3,1); + if nargin < 2, + om = zeros(3,1); + if nargin < 1, + error('Need at least a 3D structure to project (in project_points.m)'); + return; + end; + end; + end; + end; + end; + end; +end; + + +[m,n] = size(X); + +[Y,dYdom,dYdT] = rigid_motion(X,om,T); + + +inv_Z = 1./Y(3,:); + +x = (Y(1:2,:) .* (ones(2,1) * inv_Z)) ; + + +bb = (-x(1,:) .* inv_Z)'*ones(1,3); +cc = (-x(2,:) .* inv_Z)'*ones(1,3); + + +dxdom = zeros(2*n,3); +dxdom(1:2:end,:) = ((inv_Z')*ones(1,3)) .* dYdom(1:3:end,:) + bb .* dYdom(3:3:end,:); +dxdom(2:2:end,:) = ((inv_Z')*ones(1,3)) .* dYdom(2:3:end,:) + cc .* dYdom(3:3:end,:); + +dxdT = zeros(2*n,3); +dxdT(1:2:end,:) = ((inv_Z')*ones(1,3)) .* dYdT(1:3:end,:) + bb .* dYdT(3:3:end,:); +dxdT(2:2:end,:) = ((inv_Z')*ones(1,3)) .* dYdT(2:3:end,:) + cc .* dYdT(3:3:end,:); + + +% Add distortion: + +r2 = x(1,:).^2 + x(2,:).^2; + + + +dr2dom = 2*((x(1,:)')*ones(1,3)) .* dxdom(1:2:end,:) + 2*((x(2,:)')*ones(1,3)) .* dxdom(2:2:end,:); +dr2dT = 2*((x(1,:)')*ones(1,3)) .* dxdT(1:2:end,:) + 2*((x(2,:)')*ones(1,3)) .* dxdT(2:2:end,:); + + +r4 = r2.^2; + +dr4dom = 2*((r2')*ones(1,3)) .* dr2dom; +dr4dT = 2*((r2')*ones(1,3)) .* dr2dT; + + +% Radial distortion: + +cdist = 1 + k(1) * r2 + k(2) * r4; + +dcdistdom = k(1) * dr2dom + k(2) * dr4dom; +dcdistdT = k(1) * dr2dT+ k(2) * dr4dT; +dcdistdk = [ r2' r4' zeros(n,2)]; + + +xd1 = x .* (ones(2,1)*cdist); + +dxd1dom = zeros(2*n,3); +dxd1dom(1:2:end,:) = (x(1,:)'*ones(1,3)) .* dcdistdom; +dxd1dom(2:2:end,:) = (x(2,:)'*ones(1,3)) .* dcdistdom; +coeff = (reshape([cdist;cdist],2*n,1)*ones(1,3)); +dxd1dom = dxd1dom + coeff.* dxdom; + +dxd1dT = zeros(2*n,3); +dxd1dT(1:2:end,:) = (x(1,:)'*ones(1,3)) .* dcdistdT; +dxd1dT(2:2:end,:) = (x(2,:)'*ones(1,3)) .* dcdistdT; +dxd1dT = dxd1dT + coeff.* dxdT; + +dxd1dk = zeros(2*n,4); +dxd1dk(1:2:end,:) = (x(1,:)'*ones(1,4)) .* dcdistdk; +dxd1dk(2:2:end,:) = (x(2,:)'*ones(1,4)) .* dcdistdk; + + + +% tangential distortion: + +a1 = 2.*x(1,:).*x(2,:); +a2 = r2 + 2*x(1,:).^2; +a3 = r2 + 2*x(2,:).^2; + +delta_x = [k(3)*a1 + k(4)*a2 ; + k(3) * a3 + k(4)*a1]; + + +ddelta_xdx = zeros(2*n,2*n); +aa = (2*k(3)*x(2,:)+6*k(4)*x(1,:))'*ones(1,3); +bb = (2*k(3)*x(1,:)+2*k(4)*x(2,:))'*ones(1,3); +cc = (6*k(3)*x(2,:)+2*k(4)*x(1,:))'*ones(1,3); + +ddelta_xdom = zeros(2*n,3); +ddelta_xdom(1:2:end,:) = aa .* dxdom(1:2:end,:) + bb .* dxdom(2:2:end,:); +ddelta_xdom(2:2:end,:) = bb .* dxdom(1:2:end,:) + cc .* dxdom(2:2:end,:); + +ddelta_xdT = zeros(2*n,3); +ddelta_xdT(1:2:end,:) = aa .* dxdT(1:2:end,:) + bb .* dxdT(2:2:end,:); +ddelta_xdT(2:2:end,:) = bb .* dxdT(1:2:end,:) + cc .* dxdT(2:2:end,:); + +ddelta_xdk = zeros(2*n,4); +ddelta_xdk(1:2:end,3) = a1'; +ddelta_xdk(1:2:end,4) = a2'; +ddelta_xdk(2:2:end,3) = a3'; +ddelta_xdk(2:2:end,4) = a1'; + + + +xd2 = xd1 + delta_x; + +dxd2dom = dxd1dom + ddelta_xdom ; +dxd2dT = dxd1dT + ddelta_xdT; +dxd2dk = dxd1dk + ddelta_xdk ; + + +% Add Skew: + +xd3 = [xd2(1,:) + alpha*xd2(2,:);xd2(2,:)]; + +% Compute: dxd3dom, dxd3dT, dxd3dk, dxd3dalpha + +dxd3dom = zeros(2*n,3); +dxd3dom(1:2:2*n,:) = dxd2dom(1:2:2*n,:) + alpha*dxd2dom(2:2:2*n,:); +dxd3dom(2:2:2*n,:) = dxd2dom(2:2:2*n,:); +dxd3dT = zeros(2*n,3); +dxd3dT(1:2:2*n,:) = dxd2dT(1:2:2*n,:) + alpha*dxd2dT(2:2:2*n,:); +dxd3dT(2:2:2*n,:) = dxd2dT(2:2:2*n,:); +dxd3dk = zeros(2*n,4); +dxd3dk(1:2:2*n,:) = dxd2dk(1:2:2*n,:) + alpha*dxd2dk(2:2:2*n,:); +dxd3dk(2:2:2*n,:) = dxd2dk(2:2:2*n,:); +dxd3dalpha = zeros(2*n,1); +dxd3dalpha(1:2:2*n,:) = xd2(2,:)'; + + + +% Pixel coordinates: + +xp = xd3 .* (f * ones(1,n)) + c*ones(1,n); + +coeff = reshape(f*ones(1,n),2*n,1); + +dxpdom = (coeff*ones(1,3)) .* dxd3dom; +dxpdT = (coeff*ones(1,3)) .* dxd3dT; +dxpdk = (coeff*ones(1,4)) .* dxd3dk; +dxpdalpha = (coeff) .* dxd3dalpha; + +dxpdf = zeros(2*n,2); +dxpdf(1:2:end,1) = xd2(1,:)'; +dxpdf(2:2:end,2) = xd2(2,:)'; + +dxpdc = zeros(2*n,2); +dxpdc(1:2:end,1) = ones(n,1); +dxpdc(2:2:end,2) = ones(n,1); + + +return; + +% Test of the Jacobians: + +n = 10; + +X = 10*randn(3,n); +om = randn(3,1); +T = [10*randn(2,1);40]; +f = 1000*rand(2,1); +c = 1000*randn(2,1); +k = 0.5*randn(4,1); +alpha = 0.01*randn(1,1); + +[x,dxdom,dxdT,dxdf,dxdc,dxdk,dxdalpha] = project_points2(X,om,T,f,c,k,alpha); + + +% Test on om: NOT OK + +dom = 0.000000001 * norm(om)*randn(3,1); +om2 = om + dom; + +[x2] = project_points2(X,om2,T,f,c,k,alpha); + +x_pred = x + reshape(dxdom * dom,2,n); + + +norm(x2-x)/norm(x2 - x_pred) + + +% Test on T: OK!! + +dT = 0.0001 * norm(T)*randn(3,1); +T2 = T + dT; + +[x2] = project_points2(X,om,T2,f,c,k,alpha); + +x_pred = x + reshape(dxdT * dT,2,n); + + +norm(x2-x)/norm(x2 - x_pred) + + + +% Test on f: OK!! + +df = 0.001 * norm(f)*randn(2,1); +f2 = f + df; + +[x2] = project_points2(X,om,T,f2,c,k,alpha); + +x_pred = x + reshape(dxdf * df,2,n); + + +norm(x2-x)/norm(x2 - x_pred) + + +% Test on c: OK!! + +dc = 0.01 * norm(c)*randn(2,1); +c2 = c + dc; + +[x2] = project_points2(X,om,T,f,c2,k,alpha); + +x_pred = x + reshape(dxdc * dc,2,n); + +norm(x2-x)/norm(x2 - x_pred) + +% Test on k: OK!! + +dk = 0.001 * norm(k)*randn(4,1); +k2 = k + dk; + +[x2] = project_points2(X,om,T,f,c,k2,alpha); + +x_pred = x + reshape(dxdk * dk,2,n); + +norm(x2-x)/norm(x2 - x_pred) + + +% Test on alpha: OK!! + +dalpha = 0.001 * norm(k)*randn(1,1); +alpha2 = alpha + dalpha; + +[x2] = project_points2(X,om,T,f,c,k,alpha2); + +x_pred = x + reshape(dxdalpha * dalpha,2,n); + +norm(x2-x)/norm(x2 - x_pred) diff --git a/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/projectedGrid.m b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/projectedGrid.m new file mode 100755 index 0000000..561a7d0 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/projectedGrid.m @@ -0,0 +1,24 @@ +function [XX,H] = projectedGrid ( P1, P2, P3, P4 , nx, ny); + +% new formalism using homographies + +a00 = [P1;1]; +a10 = [P2;1]; +a11 = [P3;1]; +a01 = [P4;1]; + +% Compute the planart collineation: + +[H] = compute_collineation (a00, a10, a11, a01); + + +% Build the grid using the planar collineation: + +x_l = ((0:(nx-1))'*ones(1,ny))/(nx-1); +y_l = (ones(nx,1)*(0:(ny-1)))/(ny-1); + +pts = [x_l(:) y_l(:) ones(nx*ny,1)]'; + +XX = H*pts; + +XX = XX(1:2,:) ./ (ones(2,1)*XX(3,:)); diff --git a/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/projector_calib.m b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/projector_calib.m new file mode 100755 index 0000000..bb4ef86 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/projector_calib.m @@ -0,0 +1,258 @@ +%%% This code is an additional code that helps doing projector calibration in 3D scanning setup. +%%% This is not a useful code for anyone else but me. +%%% I included it in the toolbox for illustration only. + + +load camera_results; + + +proj_name = input('Basename projector calibration images (without number nor suffix): ','s'); + + +i = 1; + +while (i <= n_ima), % & (~no_image_file), + + if active_images(i), + + %fprintf(1,'Loading image %d...\n',i); + + if ~type_numbering, + number_ext = num2str(image_numbers(i)); + else + number_ext = sprintf(['%.' num2str(N_slots) 'd'],image_numbers(i)); + end; + + ima_namep = [proj_name number_ext 'p.' format_image]; + ima_namen = [proj_name number_ext 'n.' format_image]; + + if i == ind_active(1), + fprintf(1,'Loading image '); + end; + + fprintf(1,'%d...',i); + + if format_image(1) == 'p', + if format_image(2) == 'p', + Ip = double(loadppm(ima_namep)); + In = double(loadppm(ima_namen)); + else + Ip = double(loadpgm(ima_namep)); + In = double(loadpgm(ima_namen)); + end; + else + if format_image(1) == 'r', + Ip = readras(ima_namep); + In = readras(ima_namen); + else + Ip = double(imread(ima_namep)); + In = double(imread(ima_namen)); + end; + end; + + + if size(Ip,3)>1, + Ip = Ip(:,:,2); + In = In(:,:,2); + end; + + eval(['Ip_' num2str(i) ' = Ip;']); + eval(['In_' num2str(i) ' = In;']); + + end; + + i = i+1; + +end; + + +fprintf(1,'\nExtraction of the grid corners on the image\n'); + +disp('Window size for corner finder (wintx and winty):'); +wintx = input('wintx ([] = 5) = '); +if isempty(wintx), wintx = 5; end; +wintx = round(wintx); +winty = input('winty ([] = 5) = '); +if isempty(winty), winty = 5; end; +winty = round(winty); +fprintf(1,'Window size = %dx%d\n',2*wintx+1,2*winty+1); + + +disp('The projector you are using is the DLP or Intel'); +nx = 800; +ny = 600; + +dX = input('Size dX in x of the squares (in pixels) [50] = '); +dY = input('Size dY in y of the squares (in pixels) [50] = '); + +if isempty(dX), dX=50; end; +if isempty(dY), dY=50; end; + +dXoff = input('Position in x of your reference (in pixels) [399.5] = '); +dYoff = input('Position in y of your reference (in pixels) [299.5] = '); + +if isempty(dXoff), dXoff=399.5; end; +if isempty(dYoff), dYoff=299.5; end; + +end; + + + +for kk = ind_active, + + eval(['Ip = Ip_' num2str(kk) ';']); + eval(['In = In_' num2str(kk) ';']); + + [x,X,n_sq_x,n_sq_y,ind_orig,ind_x,ind_y] = extract_grid(In,wintx,winty,fc,cc,kc,dX,dY); + xproj = x; + + Np_proj = size(x,2); + + figure(2); + image(Ip); + hold on; + plot(xproj(1,:)+1,xproj(2,:)+1,'r+'); + title('Click on your reference point'); + xlabel('Xc (in camera frame)'); + ylabel('Yc (in camera frame)'); + hold off; + + disp('Click on your reference point...'); + + [xr,yr] = ginput2(1); + + err = sqrt(sum((xproj - [xr;yr]*ones(1,Np_proj)).^2)); + ind_ref = find(err == min(err)); + + ref_pt = xproj(:,ind_ref); + + + figure(2); + hold on; + plot(ref_pt(1)+1,ref_pt(2)+1,'go'); hold off; + + + nn = floor(ind_ref/(n_sq_x+1)); + off_x = ind_ref - nn*(n_sq_x+1) - 1; + off_y = n_sq_y - nn; + + + xprojn = xproj - cc * ones(1,Np_proj); + xprojn = xprojn ./ (fc * ones(1,Np_proj)); + xprojn = comp_distortion(xprojn,kc); + + eval(['Rc = Rc_' num2str(kk) ';']); + eval(['Tc = Tc_' num2str(kk) ';']); + + Zc = ((Rc(:,3)'*Tc) * (1./(Rc(:,3)' * [xprojn; ones(1,Np_proj)]))); + Xcp = (ones(3,1)*Zc) .* [xprojn; ones(1,Np_proj)]; % % in the camera frame + %Xproj = Rc'* Xcp - (Rc'*Tc)*ones(1,Np); % in the object frame !!! it works! + %Xproj(3,:) = zeros(1,Np); + + eval(['X_proj_' num2str(kk) ' = Xcp;']); % coordinates of the points in the + + x_proj = X(1:2,:) + ([dXoff - dX * off_x ; dYoff - dY * off_y]*ones(1,Np_proj)); + + eval(['x_proj_' num2str(kk) ' = x_proj;']); % coordinates of the points in the + +end; + + + +X_proj = []; +x_proj = []; + +for kk = ind_active, + eval(['X_proj = [X_proj X_proj_' num2str(kk) '];']); + eval(['x_proj = [x_proj x_proj_' num2str(kk) '];']); +end; + + +%Save camera parameters: +fc_save = fc; +cc_save = cc; +kc_save = kc; + +omc_1_save = omc_1; +Rc_1_save = Rc_1; +Tc_1_save = Tc_1; + + +% Get started to calibrate projector: +clear fc cc kc + +n_ima = 1; +X_1 = X_proj; +x_1 = x_proj; + + +% Image size: (may or may not be available) + +nx = 800; +ny = 600; + +% No calibration image is available (only the corner coordinates) + +no_image = 1; + +% Set the toolbox not to prompt the user (choose default values) + +dont_ask = 1; + +% Do not estimate distortion: + +est_dist = [0;0;0;0]; +est_dist = ones(4,1); + +center_optim = 1; + +% Run the main calibration routine: + +go_calib_optim_iter; + +% Shows the extrinsic parameters: + +dX = 3; +dY = 3; + +ext_calib; + +% Reprojection on the original images: + +reproject_calib; + + + + +%----------------------- Retrieve results: + +% Intrinsic: + +% Projector: +fp = fc; +cp = cc; +kp = kc; + +% Camera: +fc = fc_save; +cc = cc_save; +kc = kc_save; + +% Extrinsic: + +% Relative position of projector and camera: +T = Tc_1; +om = omc_1; +R = rodrigues(om); + +% Relative prosition of camera wrt world: +omc = omc_1_save; +Rc = Rc_1_save; +Tc = Tc_1_save; + +% relative position of projector wrt world: +Rp = R*Rc; +omp = rodrigues(Rp); +Tp = T + R*Tc; + +eval(['save calib_cam_proj R om T fc fp cc cp kc kp Rc Rp Tc Tp']); diff --git a/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/readras.m b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/readras.m new file mode 100755 index 0000000..fc1820b --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/readras.m @@ -0,0 +1,87 @@ +function [X, map] = readras(filename, ys, ye, xs, xe); +%READRAS Read an image file in sun raster format. +% READRAS('imagefile.ras') reads a "sun.raster" image file. +% [X, map] = READRAS('imagefile.ras') returns both the image and a +% color map, so that +% [X, map] = readras('imagefile.ras'); +% image(X) +% colormap(map) +% axis('equal') +% will display the result with the proper colors. +% NOTE: readras cannot deal with complicated color maps. +% In fact, Matlab doesn't quite allow to work with colormaps +% with more than 64 entries. +% + +%% +%% (C) Thomas K. Leung 3/30/93. +%% California Institute of Technology. +%% Modified by Andrea Mennucci to deal with color images +%% + +% PC and UNIX version of readras - Jean-Yves Bouguet - Dec. 1998 + +dot = max(find(filename == '.')); +suffix = filename(dot+1:dot+3); + +if(strcmp(suffix, 'ras')) % raster file format % + fp = fopen(filename, 'rb'); + if(fp<0) error(['Cannot open ' filename '.']), end + + %Read and crack the 32-byte header + fseek(fp, 4, -1); + + width = 2^24 * fread(fp, 1, 'uchar') + 2^16 * fread(fp, 1, 'uchar') + 2^8 * fread(fp, 1, 'uchar') + fread(fp, 1, 'uchar'); + + height = 2^24 * fread(fp, 1, 'uchar') + 2^16 * fread(fp, 1, 'uchar') + 2^8 * fread(fp, 1, 'uchar') + fread(fp, 1, 'uchar'); + + depth = 2^24 * fread(fp, 1, 'uchar') + 2^16 * fread(fp, 1, 'uchar') + 2^8 * fread(fp, 1, 'uchar') + fread(fp, 1, 'uchar'); + + length = 2^24 * fread(fp, 1, 'uchar') + 2^16 * fread(fp, 1, 'uchar') + 2^8 * fread(fp, 1, 'uchar') + fread(fp, 1, 'uchar'); + + type = 2^24 * fread(fp, 1, 'uchar') + 2^16 * fread(fp, 1, 'uchar') + 2^8 * fread(fp, 1, 'uchar') + fread(fp, 1, 'uchar'); + + maptype = 2^24 * fread(fp, 1, 'uchar') + 2^16 * fread(fp, 1, 'uchar') + 2^8 * fread(fp, 1, 'uchar') + fread(fp, 1, 'uchar'); + + maplen = 2^24 * fread(fp, 1, 'uchar') + 2^16 * fread(fp, 1, 'uchar') + 2^8 * fread(fp, 1, 'uchar') + fread(fp, 1, 'uchar'); + + maplen = maplen / 3; + + if maptype == 2 % RMT_RAW + map = fread(fp, [maplen, 3], 'uchar')/255; +% if maplen<64, map=[map',zeros(3,64-maplen)]';maplen=64; end; + elseif maptype == 1 % RMT_EQUAL_RGB + map(:,1) = fread(fp, [maplen], 'uchar'); + map(:,2) = fread(fp, [maplen], 'uchar'); + map(:,3) = fread(fp, [maplen], 'uchar'); + %maxmap = max(max(map)); + map = map/255; + if maplen<64, map=[map',zeros(3,64-maplen)]'; maplen=64; end; + else % RMT_NONE + map = []; + end +% if maplen>64, +% map=[map',zeros(3,256-maplen)]'; +% end; + + % Read the image + + if rem(width,2) == 1 + Xt = fread(fp, [width+1, height], 'uchar'); + X = Xt(1:width, :)'; + else + Xt = fread(fp, [width, height], 'uchar'); + X = Xt'; + end + X = X + 1; + fclose(fp); +else + error('Image file name must end in either ''ras'' or ''rast''.'); +end + + +if nargin == 5 + + X = X(ys:ye, xs:xe); + +end \ No newline at end of file diff --git a/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/recomp_corner_calib.m b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/recomp_corner_calib.m new file mode 100755 index 0000000..0909c69 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/recomp_corner_calib.m @@ -0,0 +1,119 @@ +% Re-select te corners after calibration + +if ~exist('n_ima')|~exist('fc'), + fprintf(1,'No calibration data available.\n'); + return; +end; + +check_active_images; + +flag = 0; +for kk = ind_active, + if ~exist(['y_' num2str(kk)]), + flag = 1; + else + eval(['ykk = y_' num2str(kk) ';']); + if isnan(ykk(1,1)), + flag = 1; + end; + end; +end; + +if flag, + fprintf(1,'Need to calibrate once before before recomputing image corners. Maybe need to load Calib_Results.mat file.\n'); + return; +end; + + +if ~exist(['I_' num2str(ind_active(1))]), + n_ima_save = n_ima; + active_images_save = active_images; + ima_read_calib; + n_ima = n_ima_save; + active_images = active_images_save; + check_active_images; + if no_image_file, + disp('Cannot extract corners without images'); + return; + end; +end; + +fprintf(1,'\nRe-extraction of the grid corners on the images (after first calibration)\n'); + +disp('Window size for corner finder (wintx and winty):'); +wintx = input('wintx ([] = 5) = '); +if isempty(wintx), wintx = 5; end; +wintx = round(wintx); +winty = input('winty ([] = 5) = '); +if isempty(winty), winty = 5; end; +winty = round(winty); + +fprintf(1,'Window size = %dx%d\n',2*wintx+1,2*winty+1); + +ima_numbers = input('Number(s) of image(s) to process ([] = all images) = '); + +if isempty(ima_numbers), + ima_proc = 1:n_ima; +else + ima_proc = ima_numbers; +end; + +q_auto = input('Use the projection of 3D grid or manual click ([]=auto, other=manual): '); + +fprintf(1,'Processing image '); + +for kk = ima_proc; + + if active_images(kk), + + fprintf(1,'%d...',kk); + + if isempty(q_auto), + + eval(['I = I_' num2str(kk) ';']); + + eval(['y = y_' num2str(kk) ';']); + + xc = cornerfinder(y+1,I,winty,wintx); % the four corners + + eval(['wintx_' num2str(kk) ' = wintx;']); + eval(['winty_' num2str(kk) ' = winty;']); + + eval(['x_' num2str(kk) '= xc - 1;']); + + else + + fprintf(1,'\n'); + + click_ima_calib; + + end; + + else + + if ~exist(['omc_' num2str(kk)]), + + eval(['dX_' num2str(kk) ' = NaN;']); + eval(['dY_' num2str(kk) ' = NaN;']); + + eval(['wintx_' num2str(kk) ' = NaN;']); + eval(['winty_' num2str(kk) ' = NaN;']); + + eval(['x_' num2str(kk) ' = NaN*ones(2,1);']); + eval(['X_' num2str(kk) ' = NaN*ones(3,1);']); + + eval(['n_sq_x_' num2str(kk) ' = NaN;']); + eval(['n_sq_y_' num2str(kk) ' = NaN;']); + + end; + + end; + + +end; + +% Recompute the error: + +comp_error_calib; + +fprintf(1,'\ndone\n'); \ No newline at end of file diff --git a/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/rect.m b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/rect.m new file mode 100755 index 0000000..ccac7a5 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/rect.m @@ -0,0 +1,127 @@ +function [Irec] = rect(I,R,f,c,k,alpha,KK_new); + + +if nargin < 5, + k = 0; + if nargin < 4, + c = [0;0]; + if nargin < 3, + f = [1;1]; + if nargin < 2, + R = eye(3); + if nargin < 1, + error('ERROR: Need an image to rectify'); + break; + end; + end; + end; + end; +end; + + +if nargin < 7, + if nargin < 6, + KK_new = [f(1) 0 c(1);0 f(2) c(2);0 0 1]; + else + KK_new = alpha; % the 6th argument is actually KK_new + end; + alpha = 0; +end; + + + +% Note: R is the motion of the points in space +% So: X2 = R*X where X: coord in the old reference frame, X2: coord in the new ref frame. + + +if ~exist('KK_new'), + KK_new = [f(1) alpha_c*fc(1) c(1);0 f(2) c(2);0 0 1]; +end; + + +[nr,nc] = size(I); + +Irec = 255*ones(nr,nc); + +[mx,my] = meshgrid(1:nc, 1:nr); +px = reshape(mx',nc*nr,1); +py = reshape(my',nc*nr,1); + +rays = inv(KK_new)*[(px - 1)';(py - 1)';ones(1,length(px))]; + + +% Rotation: (or affine transformation): + +rays2 = R'*rays; + +x = [rays2(1,:)./rays2(3,:);rays2(2,:)./rays2(3,:)]; + + +% Add distortion: + +k1 = k(1); +k2 = k(2); + +p1 = k(3); +p2 = k(4); + +r_2 = sum(x.^2); + +delta_x = [2*p1*x(1,:).*x(2,:) + p2*(r_2 + 2*x(1,:).^2) ; + p1 * (r_2 + 2*x(2,:).^2)+2*p2*x(1,:).*x(2,:)]; + +xd = (ones(2,1)*( 1 + k1 * r_2 + k2 * r_2.^2)) .* x + delta_x; + + +% Reconvert in pixels: + +px2 = f(1)*(xd(1,:)+alpha_c*xd(2,:))+c(1); +py2 = f(2)*xd(2,:)+c(2); + + +% Interpolate between the closest pixels: + +px_0 = floor(px2); +px_1 = px_0 + 1; +alpha_x = px2 - px_0; + +py_0 = floor(py2); +py_1 = py_0 + 1; +alpha_y = py2 - py_0; + +good_points = find((px_0 >= 0) & (px_1 <= (nc-1)) & (py_0 >= 0) & (py_1 <= (nr-1))); + +I_lu = I(px_0(good_points) * nr + py_0(good_points) + 1); +I_ru = I(px_1(good_points) * nr + py_0(good_points) + 1); +I_ld = I(px_0(good_points) * nr + py_1(good_points) + 1); +I_rd = I(px_1(good_points) * nr + py_1(good_points) + 1); + + +I_interp = (1 - alpha_y(good_points)).*((1 - alpha_x(good_points)).* I_lu + alpha_x(good_points) .* I_ru) + alpha_y(good_points) .* ((1 - alpha_x(good_points)).* I_ld + alpha_x(good_points) .* I_rd); + + +Irec((px(good_points)-1)*nr + py(good_points)) = I_interp; + + + +return; + + +% Convert in indices: + +fact = 3; + +[XX,YY]= meshgrid(1:nc,1:nr); +[XXi,YYi]= meshgrid(1:1/fact:nc,1:1/fact:nr); + +%tic; +Iinterp = interp2(XX,YY,I,XXi,YYi); +%toc + +[nri,nci] = size(Iinterp); + + +ind_col = round(fact*(f(1)*xd(1,:)+c(1)))+1; +ind_row = round(fact*(f(2)*xd(2,:)+c(2)))+1; + +good_points = find((ind_col >=1)&(ind_col<=nci)&(ind_row >=1)& (ind_row <=nri)); diff --git a/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/reproject_calib.m b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/reproject_calib.m new file mode 100755 index 0000000..d3ad3d2 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/reproject_calib.m @@ -0,0 +1,121 @@ +%%%%%%%%%%%%%%%%%%%% REPROJECT ON THE IMAGES %%%%%%%%%%%%%%%%%%%%%%%% + +if ~exist('n_ima')|~exist('fc'), + fprintf(1,'No calibration data available.\n'); + return; +end; + +if ~exist('no_image'), + no_image = 0; +end; + +if ~exist('nx')&~exist('ny'), + fprintf(1,'WARNING: No image size (nx,ny) available. Setting nx=640 and ny=480\n'); + nx = 640; + ny = 480; +end; + + +check_active_images; + + +% Color code for each image: + +colors = 'brgkcm'; + +% Reproject the patterns on the images, and compute the pixel errors: + +% Reload the images if necessary + +if ~exist(['omc_' num2str(ind_active(1)) ]), + fprintf(1,'Need to calibrate before showing image reprojection. Maybe need to load Calib_Results.mat file.\n'); + return; +end; + +if ~no_image, + if ~exist(['I_' num2str(ind_active(1)) ]'), + n_ima_save = n_ima; + active_images_save = active_images; + ima_read_calib; + n_ima = n_ima_save; + active_images = active_images_save; + check_active_images; + if no_image_file, + fprintf(1,'WARNING: Do not show the original images\n'); %return; + end; + end; +else + no_image_file = 1; +end; + + +if ~exist('dont_ask'), + dont_ask = 0; +end; + + +if ~dont_ask, + ima_numbers = input('Number(s) of image(s) to show ([] = all images) = '); +else + ima_numbers = []; +end; + + +if isempty(ima_numbers), + ima_proc = 1:n_ima; +else + ima_proc = ima_numbers; +end; + + +figure(5); +for kk = ima_proc, %1:n_ima, + if exist(['y_' num2str(kk)]), + if active_images(kk) & eval(['~isnan(y_' num2str(kk) '(1,1))']), + eval(['plot(ex_' num2str(kk) '(1,:),ex_' num2str(kk) '(2,:),''' colors(rem(kk-1,6)+1) '+'');']); + hold on; + end; + end; +end; +hold off; +axis('equal'); +title('Reprojection error (in pixel)'); +xlabel('x'); +ylabel('y'); +drawnow; + +set(5,'Name','error','NumberTitle','off'); + + + +for kk = ima_proc, + if exist(['y_' num2str(kk)]), + if active_images(kk) & eval(['~isnan(y_' num2str(kk) '(1,1))']), + + if exist(['I_' num2str(kk)]), + eval(['I = I_' num2str(kk) ';']); + else + I = 255*ones(ny,nx); + end; + + figure(5+kk); + image(I); hold on; + colormap(gray(256)); + title(['Image ' num2str(kk) ' - Image points (+) and reprojected grid points (o)']); + eval(['plot(x_' num2str(kk) '(1,:)+1,x_' num2str(kk) '(2,:)+1,''r+'');']); + eval(['plot(y_' num2str(kk) '(1,:)+1,y_' num2str(kk) '(2,:)+1,''' colors(rem(kk-1,6)+1) 'o'');']); + zoom on; + axis([1 nx 1 ny]); + hold off; + drawnow; + + set(5+kk,'Name',num2str(kk),'NumberTitle','off'); + + end; + end; +end; + + +err_std = std(ex')'; + +fprintf(1,'Pixel error: err = [%3.5f %3.5f] (all active images)\n\n',err_std); diff --git a/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/rigid_motion.m b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/rigid_motion.m new file mode 100755 index 0000000..473405c --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/rigid_motion.m @@ -0,0 +1,66 @@ +function [Y,dYdom,dYdT] = rigid_motion(X,om,T); + +%rigid_motion.m +% +%[Y,dYdom,dYdT] = rigid_motion(X,om,T) +% +%Computes the rigid motion transformation Y = R*X+T, where R = rodrigues(om). +% +%INPUT: X: 3D structure in the world coordinate frame (3xN matrix for N points) +% (om,T): Rigid motion parameters between world coordinate frame and camera reference frame +% om: rotation vector (3x1 vector); T: translation vector (3x1 vector) +% +%OUTPUT: Y: 3D coordinates of the structure points in the camera reference frame (3xN matrix for N points) +% dYdom: Derivative of Y with respect to om ((3N)x3 matrix) +% dYdT: Derivative of Y with respect to T ((3N)x3 matrix) +% +%Definitions: +%Let P be a point in 3D of coordinates X in the world reference frame (stored in the matrix X) +%The coordinate vector of P in the camera reference frame is: Y = R*X + T +%where R is the rotation matrix corresponding to the rotation vector om: R = rodrigues(om); +% +%Important function called within that program: +% +%rodrigues.m: Computes the rotation matrix corresponding to a rotation vector + + + +if nargin < 3, + T = zeros(3,1); + if nargin < 2, + om = zeros(3,1); + if nargin < 1, + error('Need at least a 3D structure as input (in rigid_motion.m)'); + return; + end; + end; +end; + + +[R,dRdom] = rodrigues(om); + +[m,n] = size(X); + +Y = R*X + T*ones(1,n); + +if nargout > 1, + + +dYdR = zeros(3*n,9); +dYdT = zeros(3*n,3); + +dYdR(1:3:end,1:3:end) = X'; +dYdR(2:3:end,2:3:end) = X'; +dYdR(3:3:end,3:3:end) = X'; + +dYdT(1:3:end,1) = ones(n,1); +dYdT(2:3:end,2) = ones(n,1); +dYdT(3:3:end,3) = ones(n,1); + +dYdom = dYdR * dRdom; + +end; + + + + diff --git a/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/rodrigues.m b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/rodrigues.m new file mode 100755 index 0000000..9d55337 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/rodrigues.m @@ -0,0 +1,217 @@ +function [out,dout]=rodrigues(in) + +% RODRIGUES Transform rotation matrix into rotation vector and viceversa. +% +% Sintax: [OUT]=RODRIGUES(IN) +% If IN is a 3x3 rotation matrix then OUT is the +% corresponding 3x1 rotation vector +% if IN is a rotation 3-vector then OUT is the +% corresponding 3x3 rotation matrix +% + +%% +%% Copyright (c) March 1993 -- Pietro Perona +%% California Institute of Technology +%% + +%% ALL CHECKED BY JEAN-YVES BOUGUET, October 1995. +%% FOR ALL JACOBIAN MATRICES !!! LOOK AT THE TEST AT THE END !! + +%% BUG when norm(om)=pi fixed -- April 6th, 1997; +%% Jean-Yves Bouguet + + +[m,n] = size(in); +%bigeps = 10e+4*eps; +bigeps = 10e+20*eps; + +if ((m==1) & (n==3)) | ((m==3) & (n==1)) %% it is a rotation vector + theta = norm(in); + if theta < eps + R = eye(3); + + %if nargout > 1, + + dRdin = [0 0 0; + 0 0 1; + 0 -1 0; + 0 0 -1; + 0 0 0; + 1 0 0; + 0 1 0; + -1 0 0; + 0 0 0]; + + %end; + + else + if n==length(in) in=in'; end; %% make it a column vec. if necess. + + %m3 = [in,theta] + + dm3din = [eye(3);in'/theta]; + + omega = in/theta; + + %m2 = [omega;theta] + + dm2dm3 = [eye(3)/theta -in/theta^2; zeros(1,3) 1]; + + alpha = cos(theta); + beta = sin(theta); + gamma = 1-cos(theta); + omegav=[[0 -omega(3) omega(2)];[omega(3) 0 -omega(1)];[-omega(2) omega(1) 0 ]]; + A = omega*omega'; + + %m1 = [alpha;beta;gamma;omegav;A]; + + dm1dm2 = zeros(21,4); + dm1dm2(1,4) = -sin(theta); + dm1dm2(2,4) = cos(theta); + dm1dm2(3,4) = sin(theta); + dm1dm2(4:12,1:3) = [0 0 0 0 0 1 0 -1 0; + 0 0 -1 0 0 0 1 0 0; + 0 1 0 -1 0 0 0 0 0]'; + + w1 = omega(1); + w2 = omega(2); + w3 = omega(3); + + dm1dm2(13:21,1) = [2*w1;w2;w3;w2;0;0;w3;0;0]; + dm1dm2(13: 21,2) = [0;w1;0;w1;2*w2;w3;0;w3;0]; + dm1dm2(13:21,3) = [0;0;w1;0;0;w2;w1;w2;2*w3]; + + R = eye(3)*alpha + omegav*beta + A*gamma; + + dRdm1 = zeros(9,21); + + dRdm1([1 5 9],1) = ones(3,1); + dRdm1(:,2) = omegav(:); + dRdm1(:,4:12) = beta*eye(9); + dRdm1(:,3) = A(:); + dRdm1(:,13:21) = gamma*eye(9); + + dRdin = dRdm1 * dm1dm2 * dm2dm3 * dm3din; + + + end; + out = R; + dout = dRdin; + + %% it is prob. a rot matr. + elseif ((m==n) & (m==3) & (norm(in' * in - eye(3)) < bigeps)... + & (abs(det(in)-1) < bigeps)) + R = in; + + + + tr = (trace(R)-1)/2; + dtrdR = [1 0 0 0 1 0 0 0 1]/2; + theta = real(acos(tr)); + + + if sin(theta) >= 1e-5, + + dthetadtr = -1/sqrt(1-tr^2); + + dthetadR = dthetadtr * dtrdR; + % var1 = [vth;theta]; + vth = 1/(2*sin(theta)); + dvthdtheta = -vth*cos(theta)/sin(theta); + dvar1dtheta = [dvthdtheta;1]; + + dvar1dR = dvar1dtheta * dthetadR; + + + om1 = [R(3,2)-R(2,3), R(1,3)-R(3,1), R(2,1)-R(1,2)]'; + + dom1dR = [0 0 0 0 0 1 0 -1 0; + 0 0 -1 0 0 0 1 0 0; + 0 1 0 -1 0 0 0 0 0]; + + % var = [om1;vth;theta]; + dvardR = [dom1dR;dvar1dR]; + + % var2 = [om;theta]; + om = vth*om1; + domdvar = [vth*eye(3) om1 zeros(3,1)]; + dthetadvar = [0 0 0 0 1]; + dvar2dvar = [domdvar;dthetadvar]; + + + out = om*theta; + domegadvar2 = [theta*eye(3) om]; + + dout = domegadvar2 * dvar2dvar * dvardR; + + + else + if tr > 0; % case norm(om)=0; + + out = [0 0 0]'; + + dout = [0 0 0 0 0 1/2 0 -1/2 0; + 0 0 -1/2 0 0 0 1/2 0 0; + 0 1/2 0 -1/2 0 0 0 0 0]; + else % case norm(om)=pi; %% fixed April 6th + + + out = theta * (sqrt((diag(R)+1)/2).*[1;2*(R(1,2:3)>=0)'-1]); + %keyboard; + + if nargout > 1, + fprintf(1,'WARNING!!!! Jacobian domdR undefined!!!\n'); + dout = NaN*ones(3,9); + end; + end; + end; + + else + error('Neither a rotation matrix nor a rotation vector were provided'); + end; + +return; + +%% test of the Jacobians: + +%%%% TEST OF dRdom: +om = randn(3,1); +dom = randn(3,1)/1000000; + +[R1,dR1] = rodrigues(om); +R2 = rodrigues(om+dom); + +R2a = R1 + reshape(dR1 * dom,3,3); + +gain = norm(R2 - R1)/norm(R2 - R2a) + +%%% TEST OF dOmdR: +om = randn(3,1); +R = rodrigues(om); +dom = randn(3,1)/10000; +dR = rodrigues(om+dom) - R; + +[omc,domdR] = rodrigues(R); +[om2] = rodrigues(R+dR); + +om_app = omc + domdR*dR(:); + +gain = norm(om2 - omc)/norm(om2 - om_app) + + +%%% OTHER BUG: (FIXED NOW!!!) + +omu = randn(3,1); +omu = omu/norm(omu) +om = pi*omu; +[R,dR]= rodrigues(om); +[om2] = rodrigues(R); +[om om2] + +%%% NORMAL OPERATION + +om = randn(3,1); +[R,dR]= rodrigues(om); +[om2] = rodrigues(R); +[om om2] + diff --git a/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/rotation.m b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/rotation.m new file mode 100755 index 0000000..87ee2fe --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/rotation.m @@ -0,0 +1,23 @@ +function [] = rotation(st); + +if nargin < 1, + st= 1; +end; + + +fig = gcf; + +ax = gca; + +vv = get(ax,'view'); + +az = vv(1); +el = vv(2); + +for azi = az:-abs(st):az-360, + + set(ax,'view',[azi el]); + figure(fig); + drawnow; + +end; diff --git a/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/run_error_analysis.m b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/run_error_analysis.m new file mode 100755 index 0000000..095e17e --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/run_error_analysis.m @@ -0,0 +1,65 @@ +%%% Program that launchs the complete + +for N_ima_active = 1:30, + + error_analysis; + +end; + + + +return; + + +f = []; +f_std = []; + +c = []; +c_std = []; + +k = []; +k_std = []; + +NN = 30; + +for rr = 1:NN, + + load(['Calib_Accuracies_' num2str(rr)]); + + [m1,s1] = mean_std_robust(fc_list(1,:)); + [m2,s2] = mean_std_robust(fc_list(2,:)); + + f = [f [m1;m2]]; + f_std = [f_std [s1;s2]]; + + [m1,s1] = mean_std_robust(cc_list(1,:)); + [m2,s2] = mean_std_robust(cc_list(2,:)); + + c = [c [m1;m2]]; + c_std = [c_std [s1;s2]]; + + [m1,s1] = mean_std_robust(kc_list(1,:)); + [m2,s2] = mean_std_robust(kc_list(2,:)); + [m3,s3] = mean_std_robust(kc_list(3,:)); + [m4,s4] = mean_std_robust(kc_list(4,:)); + + k = [k [m1;m2;m3;m4]]; + k_std = [k_std [s1;s2;s3;s4]]; + +end; + +figure(1); +errorbar([1:NN;1:NN]',f',f_std'); +figure(2); +errorbar([1:NN;1:NN]',c',c_std'); +figure(3); +errorbar([1:NN;1:NN;1:NN;1:NN]',k',k_std'); + +figure(4); +semilogy(f_std'); + +figure(5); +semilogy(c_std'); + +figure(6); +semilogy(k_std'); diff --git a/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/saveinr.m b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/saveinr.m new file mode 100755 index 0000000..a176e39 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/saveinr.m @@ -0,0 +1,46 @@ +%SAVEINR Write an INRIMAGE format file +% +% SAVEINR(filename, im) +% +% Saves the specified image array in a INRIA image format file. +% +% SEE ALSO: loadinr +% +% Copyright (c) Peter Corke, 1999 Machine Vision Toolbox for Matlab + +% Peter Corke 1996 + +function saveinr(fname, im) + + fid = fopen(fname, 'w'); + [r,c] = size(im'); + + % build the header + hdr = []; + s = sprintf('#INRIMAGE-4#{\n'); + hdr = [hdr s]; + s = sprintf('XDIM=%d\n',c); + hdr = [hdr s]; + s = sprintf('YDIM=%d\n',r); + hdr = [hdr s]; + s = sprintf('ZDIM=1\n'); + hdr = [hdr s]; + s = sprintf('VDIM=1\n'); + hdr = [hdr s]; + s = sprintf('TYPE=float\n'); + hdr = [hdr s]; + s = sprintf('PIXSIZE=32\n'); + hdr = [hdr s]; + s = sprintf('SCALE=2**0\n'); + hdr = [hdr s]; + s = sprintf('CPU=sun\n#'); + hdr = [hdr s]; + + % make it 256 bytes long and write it + hdr256 = zeros(1,256); + hdr256(1:length(hdr)) = hdr; + fwrite(fid, hdr256, 'uchar'); + + % now the binary data + fwrite(fid, im', 'float32'); + fclose(fid) diff --git a/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/savepgm.m b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/savepgm.m new file mode 100755 index 0000000..0cee75d --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/savepgm.m @@ -0,0 +1,22 @@ +%SAVEPGM Write a PGM format file +% +% SAVEPGM(filename, im) +% +% Saves the specified image array in a binary (P5) format PGM image file. +% +% SEE ALSO: loadpgm +% +% Copyright (c) Peter Corke, 1999 Machine Vision Toolbox for Matlab + + +% Peter Corke 1994 + +function savepgm(fname, im) + + fid = fopen(fname, 'w'); + [r,c] = size(im'); + fprintf(fid, 'P5\n'); + fprintf(fid, '%d %d\n', r, c); + fprintf(fid, '255\n'); + fwrite(fid, im', 'uchar'); + fclose(fid); diff --git a/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/saveppm.m b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/saveppm.m new file mode 100755 index 0000000..ece092b --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/saveppm.m @@ -0,0 +1,45 @@ +%SAVEPPM Write a PPM format file +% +% SAVEPPM(filename, I) +% +% Saves the specified red, green and blue planes in a binary (P6) +% format PPM image file. +% +% SEE ALSO: loadppm +% +% Copyright (c) Peter Corke, 1999 Machine Vision Toolbox for Matlab + + +% Peter Corke 1994 + +function saveppm(fname, I) + +I = double(I); + +if size(I,3) == 1, + R = I; + G = I; + B = I; +else + R = I(:,:,1); + G = I(:,:,2); + B = I(:,:,3); +end; + +%keyboard; + + fid = fopen(fname, 'w'); + [r,c] = size(R'); + fprintf(fid, 'P6\n'); + fprintf(fid, '%d %d\n', r, c); + fprintf(fid, '255\n'); + R = R'; + G = G'; + B = B'; + im = [R(:) G(:) B(:)]; + %im = reshape(im,r,c*3); + im = im'; + %im = im(:); + fwrite(fid, im, 'uchar'); + fclose(fid); + diff --git a/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/saving_calib.m b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/saving_calib.m new file mode 100755 index 0000000..3f98a8b --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/saving_calib.m @@ -0,0 +1,95 @@ + +if ~exist('n_ima')|~exist('fc'), + fprintf(1,'No calibration data available.\n'); + return; +end; + +check_active_images; + +if ~exist('solution_init'), solution_init = []; end; + +for kk = 1:n_ima, + if ~exist(['dX_' num2str(kk)]), eval(['dX_' num2str(kk) '= dX;']); end; + if ~exist(['dY_' num2str(kk)]), eval(['dY_' num2str(kk) '= dY;']); end; +end; + +if ~exist('param_list'), + param_list = solution; +end; + +if ~exist('wintx'), + wintx = []; + winty = []; +end; + +if ~exist('dX_default'), + dX_default = []; + dY_default = []; +end; + +if ~exist('alpha_c'), + alpha_c = 0; +end; + +for kk = 1:n_ima, + if ~exist(['y_' num2str(kk)]), + eval(['y_' num2str(kk) ' = NaN*ones(2,1);']); + end; + if ~exist(['n_sq_x_' num2str(kk)]), + eval(['n_sq_x_' num2str(kk) ' = NaN;']); + eval(['n_sq_y_' num2str(kk) ' = NaN;']); + end; + if ~exist(['wintx_' num2str(kk)]), + eval(['wintx_' num2str(kk) ' = NaN;']); + eval(['winty_' num2str(kk) ' = NaN;']); + end; +end; + +save_name = 'Calib_Results'; + +if exist([ save_name '.mat'])==2, + disp('WARNING: File Calib_Results.mat already exists'); + pfn = -1; + cont = 1; + while cont, + pfn = pfn + 1; + postfix = ['_old'num2str(pfn)]; + save_name = [ 'Calib_Results' postfix]; + cont = (exist([ save_name '.mat'])==2); + end; + copyfile('Calib_Results.mat',[save_name '.mat']); + disp(['Copying the current Calib_Results.mat file to ' save_name '.mat']); +end; + + +save_name = 'Calib_Results'; + +if exist('calib_name'), + + fprintf(1,['\nSaving calibration results under ' save_name '.mat\n']); + + string_save = ['save ' save_name ' center_optim param_list active_images ind_active center_optim est_alpha est_dist fc kc cc alpha_c ex x y solution solution_init wintx winty n_ima type_numbering N_slots small_calib_image first_num image_numbers format_image calib_name Hcal Wcal nx ny map dX_default dY_default KK inv_KK dX dY']; + + for kk = 1:n_ima, + string_save = [string_save ' X_' num2str(kk) ' x_' num2str(kk) ' y_' num2str(kk) ' ex_' num2str(kk) ' omc_' num2str(kk) ' Rc_' num2str(kk) ' Tc_' num2str(kk) ' H_' num2str(kk) ' n_sq_x_' num2str(kk) ' n_sq_y_' num2str(kk) ' wintx_' num2str(kk) ' winty_' num2str(kk) ' dX_' num2str(kk) ' dY_' num2str(kk)]; + end; + +else + + fprintf(1,['\nSaving calibration results under ' save_name '.mat (no image version)\n']); + + string_save = ['save ' save_name ' center_optim param_list active_images ind_active center_optim est_alpha est_dist fc kc cc alpha_c ex x y solution solution_init wintx winty n_ima nx ny dX_default dY_default KK inv_KK dX dY']; + + for kk = 1:n_ima, + string_save = [string_save ' X_' num2str(kk) ' x_' num2str(kk) ' y_' num2str(kk) ' ex_' num2str(kk) ' omc_' num2str(kk) ' Rc_' num2str(kk) ' Tc_' num2str(kk) ' H_' num2str(kk) ' n_sq_x_' num2str(kk) ' n_sq_y_' num2str(kk) ' wintx_' num2str(kk) ' winty_' num2str(kk) ' dX_' num2str(kk) ' dY_' num2str(kk)]; + end; + +end; + + + +%fprintf(1,'To load later click on Load\n'); + +eval(string_save); + +fprintf(1,'done\n'); \ No newline at end of file diff --git a/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/script_fit_distortion.m b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/script_fit_distortion.m new file mode 100755 index 0000000..c5e5430 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/script_fit_distortion.m @@ -0,0 +1,39 @@ + + satis_distort = 0; + + disp(['Estimated focal: ' num2str(f_g) ' pixels']); + + while ~satis_distort, + + k_g = input('Guess for distortion factor kc ([]=0): '); + + if isempty(k_g), k_g = 0; end; + + xy_corners_undist = comp_distortion2([x' - c_g(1);y'-c_g(2)]/f_g,k_g); + + xu = xy_corners_undist(1,:)'; + yu = xy_corners_undist(2,:)'; + + [XXu] = projectedGrid ( [xu(1);yu(1)], [xu(2);yu(2)],[xu(3);yu(3)], [xu(4);yu(4)],n_sq_x+1,n_sq_y+1); % The full grid + + XX = (ones(2,1)*(1 + k_g * sum(XXu.^2))) .* XXu; + XX(1,:) = f_g*XX(1,:)+c_g(1); + XX(2,:) = f_g*XX(2,:)+c_g(2); + + figure(2); + image(I); + colormap(map); + zoom on; + hold on; + %plot(f_g*XXu(1,:)+c_g(1),f_g*XXu(2,:)+c_g(2),'ro'); + plot(XX(1,:),XX(2,:),'r+'); + title('The red crosses should be on the grid corners...'); + hold off; + + satis_distort = input('Satisfied with distortion? ([]=no, other=yes) '); + + satis_distort = ~isempty(satis_distort); + + + end; + \ No newline at end of file diff --git a/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/startup.m b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/startup.m new file mode 100755 index 0000000..aad0fa4 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/startup.m @@ -0,0 +1,9 @@ +% Main camera calibration toolbox: + +calib_gui; + +%calib_gui; + +path(pwd,path); + +format compact diff --git a/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/undistort_image.m b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/undistort_image.m new file mode 100755 index 0000000..d9a7574 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/undistort_image.m @@ -0,0 +1,193 @@ +%%% INPUT THE IMAGE FILE NAME: + +if ~exist('fc')|~exist('cc')|~exist('kc')|~exist('alpha_c'), + fprintf(1,'No intrinsic camera parameters available.\n'); + return; +end; + +KK = [fc(1) alpha_c*fc(1) cc(1);0 fc(2) cc(2) ; 0 0 1]; + +disp('Program that undistorts images'); +disp('The intrinsic camera parameters are assumed to be known (previously computed)'); + +fprintf(1,'\n'); + +quest = input('Do you want to undistort all the calibration images ([],0) or a new image (1)? '); + +if isempty(quest), + quest = 0; +end; + +if ~quest, + + if ~exist(['I_' num2str(ind_active(1))]), + ima_read_calib; + end; + + check_active_images; + + format_image2 = format_image; + if format_image2(1) == 'j', + format_image2 = 'bmp'; + end; + + for kk = 1:n_ima, + + if exist(['I_' num2str(kk)]), + + eval(['I = I_' num2str(kk) ';']); + [I2] = rect(I,eye(3),fc,cc,kc,KK); + + if ~type_numbering, + number_ext = num2str(image_numbers(kk)); + else + number_ext = sprintf(['%.' num2str(N_slots) 'd'],image_numbers(kk)); + end; + + ima_name2 = [calib_name '_rect' number_ext '.' format_image2]; + + fprintf(1,['Saving undistorted image under ' ima_name2 '...\n']); + + + if format_image2(1) == 'p', + if format_images2(2) == 'p', + saveppm(ima_name2,uint8(round(I2))); + else + savepgm(ima_name2,uint8(round(I2))); + end; + else + if format_image2(1) == 'r', + writeras(ima_name2,round(I2),gray(256)); + else + imwrite(uint8(round(I2)),gray(256),ima_name2,format_image2); + end; + end; + + + end; + + end; + + fprintf(1,'done\n'); + +else + + dir; + fprintf(1,'\n'); + + image_name = input('Image name (full name without extension): ','s'); + + format_image2 = '0'; + +while format_image2 == '0', + + format_image2 = input('Image format: ([]=''r''=''ras'', ''b''=''bmp'', ''t''=''tif'', ''p''=''pgm'', ''j''=''jpg'', ''m''=''ppm'') ','s'); + + if isempty(format_image2), + format_image2 = 'ras'; + end; + + if lower(format_image2(1)) == 'm', + format_image2 = 'ppm'; + else + if lower(format_image2(1)) == 'b', + format_image2 = 'bmp'; + else + if lower(format_image2(1)) == 't', + format_image2 = 'tif'; + else + if lower(format_image2(1)) == 'p', + format_image2 = 'pgm'; + else + if lower(format_image2(1)) == 'j', + format_image2 = 'jpg'; + else + if lower(format_image2(1)) == 'r', + format_image2 = 'ras'; + else + disp('Invalid image format'); + format_image2 = '0'; % Ask for format once again + end; + end; + end; + end; + end; + end; +end; + +ima_name = [image_name '.' format_image2]; + + +%%% READ IN IMAGE: + +if format_image2(1) == 'p', + if format_image2(2) == 'p', + I = double(loadppm(ima_name)); + else + I = double(loadpgm(ima_name)); + end; +else + if format_image2(1) == 'r', + I = readras(ima_name); + else + I = double(imread(ima_name)); + end; +end; + +if size(I,3)>1, + I = I(:,:,2); +end; + + +if (size(I,1)>ny)|(size(I,2)>nx), + I = I(1:ny,1:nx); +end; + + + %% SHOW THE ORIGINAL IMAGE: + + figure(2); + image(I); + colormap(gray(256)); + title('Original image (with distortion) - Stored in array I'); + drawnow; + + + %% UNDISTORT THE IMAGE: + + fprintf(1,'Computing the undistorted image...') + + [I2] = rect(I,eye(3),fc,cc,kc,alpha_c,KK); + + fprintf(1,'done\n'); + + figure(3); + image(I2); + colormap(gray(256)); + title('Undistorted image - Stored in array I2'); + drawnow; + + + %% SAVE THE IMAGE IN FILE: + + ima_name2 = [image_name '_rect.' format_image2]; + + fprintf(1,['Saving undistorted image under ' ima_name2 '...']); + + if format_image2(1) == 'p', + if format_images2(2) == 'p', + saveppm(ima_name2,uint8(round(I2))); + else + savepgm(ima_name2,uint8(round(I2))); + end; + else + if format_image2(1) == 'r', + writeras(ima_name2,round(I2),gray(256)); + else + imwrite(uint8(round(I2)),gray(256),ima_name2,format_image2); + end; + end; + + fprintf(1,'done\n'); + +end; diff --git a/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/willson_convert.m b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/willson_convert.m new file mode 100755 index 0000000..8946349 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/willson_convert.m @@ -0,0 +1,89 @@ +function [fc,cc,kc,Rc,Tc,omc,nx,ny] = willson_convert(Ncx,Nfx,dx,dy,dpx,dpy,Cx,Cy,sx,f,kappa1,Tx,Ty,Tz,Rx,Ry,Rz,p1,p2); + +%Conversion from Reg Willson's calibration format to my format + +% Conversion: + +% Focal length: +fc = [sx/dpx ; 1/dpy]*f; + +% Principal point; +cc = [Cx;Cy]; + +% Extrinsic parameters: +Rx = rodrigues([Rx;0;0]); +Ry = rodrigues([0;Ry;0]); +Rz = rodrigues([0;0;Rz]); + +Rc = Rz * Ry * Rx; + +omc = rodrigues(Rc); + +Tc = [Tx;Ty;Tz]; + + +% More tricky: Take care of the distorsion: + +Nfy = round(Nfx * 3/4); + +nx = Nfx; +ny = Nfy; + +% Select a set of DISTORTED coordinates uniformely distributed across the image: + +[xp_dist,yp_dist] = meshgrid(0:Nfx-1,0:Nfy); + +xp_dist = xp_dist(:)'; +yp_dist = yp_dist(:)'; + + +% Apply UNDISTORTION according to Willson: + +xp_sensor_dist = dpx*(xp_dist - Cx)/sx; +yp_sensor_dist = dpy*(yp_dist - Cy); + +dist_fact = 1 + kappa1*(xp_sensor_dist.^2 + yp_sensor_dist.^2); + +xp_sensor = xp_sensor_dist .* dist_fact; +yp_sensor = yp_sensor_dist .* dist_fact; + +xp = xp_sensor * sx / dpx + Cx; +yp = yp_sensor / dpy + Cy; + +ind= find((xp > 0) & (xp < Nfx-1) & (yp > 0) & (yp < Nfy-1)); + +xp = xp(ind); +yp = yp(ind); +xp_dist = xp_dist(ind); +yp_dist = yp_dist(ind); + + +% Now, find my own set of parameters: + +x_dist = [(xp_dist - cc(1))/fc(1);(yp_dist - cc(2))/fc(2)]; +x = [(xp - cc(1))/fc(1);(yp - cc(2))/fc(2)]; + +k = [0;0;0;0]; + +for kk = 1:5, + + [xd,dxddk] = apply_distortion(x,k); + + err = x_dist - xd; + + %norm(err) + + k_step = inv(dxddk'*dxddk)*(dxddk')*err(:); + + k = k + k_step; %inv(dxddk'*dxddk)*(dxddk')*err(:); + + %norm(k_step)/norm(k) + + if norm(k_step)/norm(k) < 10e-10, + break; + end; + +end; + + +kc = k; diff --git a/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/willson_read.m b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/willson_read.m new file mode 100755 index 0000000..bbde63c --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/willson_read.m @@ -0,0 +1,59 @@ +% Read in Reg Willson's data file, and convert it into my data format: + +%dir; + +%calib_file = input('Reg Willson calibration file name: ','s'); + +if exist(calib_file), + + + load(calib_file); + + inddot = find(calib_file == '.'); + + if isempty(inddot), + varname = calib_file; + else + varname = calib_file(1:inddot(1)-1); + end; + + eval(['calib_params = ' varname ';']) + + Ncx = calib_params(1); + Nfx = calib_params(2); + dx = calib_params(3); + dy = calib_params(4); + dpx = calib_params(5); + dpy = calib_params(6); + Cx = calib_params(7); + Cy = calib_params(8); + sx = calib_params(9); + f = calib_params(10); + kappa1 = calib_params(11); + Tx = calib_params(12); + Ty = calib_params(13); + Tz = calib_params(14); + Rx = calib_params(15); + Ry = calib_params(16); + Rz = calib_params(17); + p1 = calib_params(18); + p2 = calib_params(19); + + % Conversion: + [fc,cc,kc,Rc_1,Tc_1,omc_1,nx,ny] = willson_convert(Ncx,Nfx,dx,dy,dpx,dpy,Cx,Cy,sx,f,kappa1,Tx,Ty,Tz,Rx,Ry,Rz,p1,p2); + + KK = [fc(1) 0 cc(1);0 fc(2) cc(2) ; 0 0 1]; + + n_ima = 1; + + X_1 = [NaN;NaN;NaN]; + x_1 = [NaN;NaN]; + + map = gray(256); + +else + + disp(['WARNING: Calibration file ' calib_file ' not found']); + +end; + diff --git a/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/writeras.m b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/writeras.m new file mode 100755 index 0000000..c7eb7bc --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/writeras.m @@ -0,0 +1,105 @@ +function writeras(filename, image, map); +%WRITERAS Write an image file in sun raster format. +% WRITERAS('imagefile.ras', image_matrix, map) writes a +% "sun.raster" image file. + +% Written by Thomas K. Leung 3/30/93. +% @ California Institute of Technology. + + +% PC and UNIX version of writeras - Jean-Yves Bouguet - Dec. 1998 + +dot = max(find(filename == '.')); +suffix = filename(dot+1:dot+3); + +if nargin < 3, + map = []; +end; + +if(strcmp(suffix, 'ras')) + %Write header + + fp = fopen(filename, 'wb'); + if(fp < 0) error(['Cannot open ' filename '.']), end + + [height, width] = size(image); + image = image - 1; + mapsize = size(map, 1)*size(map,2); + %fwrite(fp, ... + % [1504078485, width, height, 8, height*width, 1, 1, mapsize], ... + % 'long'); + + + zero_str = '00000000'; + + % MAGIC NUMBER: + + + fwrite(fp,89,'uchar'); + fwrite(fp,166,'uchar'); + fwrite(fp,106,'uchar'); + fwrite(fp,149,'uchar'); + + width_str = dec2hex(width); + width_str = [zero_str(1:8-length(width_str)) width_str]; + + for ii = 1:2:7, + fwrite(fp,hex2dec(width_str(ii:ii+1)),'uchar'); + end; + + + height_str = dec2hex(height); + height_str = [zero_str(1:8-length(height_str)) height_str]; + + for ii = 1:2:7, + fwrite(fp,hex2dec(height_str(ii:ii+1)),'uchar'); + end; + + fwrite(fp,0,'uchar'); + fwrite(fp,0,'uchar'); + fwrite(fp,0,'uchar'); + fwrite(fp,8,'uchar'); + + ll = height*width; + ll_str = dec2hex(ll); + ll_str = [zero_str(1:8-length(ll_str)) ll_str]; + + for ii = 1:2:7, + fwrite(fp,hex2dec(ll_str(ii:ii+1)),'uchar'); + end; + + fwrite(fp,0,'uchar'); + fwrite(fp,0,'uchar'); + fwrite(fp,0,'uchar'); + fwrite(fp,1,'uchar'); + fwrite(fp,0,'uchar'); + fwrite(fp,0,'uchar'); + fwrite(fp,0,'uchar'); + fwrite(fp,~~mapsize,'uchar'); + + mapsize_str = dec2hex(mapsize); + mapsize_str = [zero_str(1:8-length(mapsize_str)) mapsize_str]; + + %keyboard; + + for ii = 1:2:7, + fwrite(fp,hex2dec(mapsize_str(ii:ii+1)),'uchar'); + end; + + + if mapsize ~= 0 + map = min(255, fix(255*map)); + fwrite(fp, map, 'uchar'); + end + if rem(width,2) == 1 + image = [image'; zeros(1, height)]'; + top = 255 * ones(size(image)); + fwrite(fp, min(top,image)', 'uchar'); + else + top = 255 * ones(size(image)); + fwrite(fp, min(top,image)', 'uchar'); + end + fclose(fp); +else + error('Image file name must end in either ''ras'' or ''rast''.'); +end diff --git a/SD-VBS/common/toolbox/toolbox_basic/affine/README b/SD-VBS/common/toolbox/toolbox_basic/affine/README new file mode 100755 index 0000000..e578a74 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/affine/README @@ -0,0 +1,5 @@ +Top level program is "compute_AD.m". Use "compute_AD_disp.m" if one +wants to display results as program runs. + +The testing programs are called "simulation.m" for synthetic images, +and "test_affine.m" for real images. diff --git a/SD-VBS/common/toolbox/toolbox_basic/affine/carve_it.m b/SD-VBS/common/toolbox/toolbox_basic/affine/carve_it.m new file mode 100755 index 0000000..1a44f89 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/affine/carve_it.m @@ -0,0 +1,25 @@ +function img = carve_it(I,center,window_size_h) + +[size_y,size_x]= size(I); +min_x = round(center(1)-window_size_h(1)); +max_x = round(center(1)+window_size_h(1)); +min_y = round(center(2)-window_size_h(2)); +max_y = round(center(2)+window_size_h(2)); +window_size = window_size_h*2 +1; + +if (min_x <1)|(max_x > size_x)|(min_y<1)|(max_y>size_y), + disp('window too big'); + center + window_size_h + img = zeros(window_size(2),window_size(1)); + n_min_x = max(1,round(min_x)); + n_min_y = max(1,round(min_y)); + n_max_x = min(size_x,round(max_x)); + n_max_y = min(size_y,round(max_y)); + img(1+(n_min_y-min_y):window_size(2)-(max_y-n_max_y),1+(n_min_x-min_x):window_size(1)-(max_x-n_max_x))=I(n_min_y:n_max_y,n_min_x:n_max_x); +else + img = I(center(2)-window_size_h(2):center(2)+window_size_h(2),... + center(1)-window_size_h(1):center(1)+window_size_h(1)); +end + + diff --git a/SD-VBS/common/toolbox/toolbox_basic/affine/compute_AD.m b/SD-VBS/common/toolbox/toolbox_basic/affine/compute_AD.m new file mode 100755 index 0000000..a39acd6 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/affine/compute_AD.m @@ -0,0 +1,90 @@ +function [A,D,mask] =... +compute_AD(img_i,img_j,center_i,center_j,window_size_h,num_iter,w,num_trans,Dest,mask) +% +% function [A,D,mask] = ... +% compute_AD(img_i,img_j,center_i,center_j,window_size_h,num_iter,w, +% mask,num_trans) +% +% A: Affine motion; +% D: Displacement; +% +% img_i, img_j: the two image(in full size); +% center_i, center_j: the centers of the feature in two images; +% window_size_h: half size of the feature window; +% num_iter: number of iterations; +% w: parameter used in "grad.m" for computing gaussians used for +% gradient estimation; +% +% num_trans: OPTIONAL, number of translation iteration; default = 3; +% mask: OPTIONAL, if some area of the square shaped feature window should +% be weighted less; +% + +% +% Jianbo Shi +% + +if ~exist('Dest'), + Dest = [0,0]; +end + +if ~exist('mask'), + mask = ones(2*window_size_h+1)'; +end + +% set the default num_trans +if ~exist('num_trans'), + num_trans= 3; +end + +% normalize image intensity to the range of 0.0-1.0 +img_i = norm_inten(img_i); +img_j = norm_inten(img_j); + +window_size = 2*window_size_h + 1; +I = carve_it(img_i,center_i,window_size_h); +J = carve_it(img_j,center_j,window_size_h); + +% init. step +J_computed = I; +D_computed = Dest; +A_computed = eye(2); +J_computed = compute_J(A_computed,D_computed,img_i,center_i,window_size_h); + +%% level of noise +sig = 0.1; + +records = zeros(num_iter,6); +errs = zeros(1,num_iter); + +k = 1; +% iteration +while k <= num_iter, + [A,D] = iter_AD(J_computed,J,mask,w,k,num_trans); + + A_computed = A*A_computed; + D_computed = (A*D_computed')' + D; + + % compute the warped image + J_computed = compute_J(A_computed,D_computed,img_i,center_i,window_size_h); + + % compute the SSD error + errs(k) = sqrt(sum(sum((mask.*(J_computed-J)).^2)))/prod(size(J)); + + % update the mask, discounting possible occlusion region + if (k>num_trans), + mask = exp(-abs(J_computed-J)/sig); + end + + % record the A and D + records(k,:) = [reshape(A_computed,1,4),reshape(D_computed,1,2)]; + + k = k+1; +end + +[tmp,id] = min(errs); +A = reshape(records(id,1:4),2,2); +D = reshape(records(id,5:6),1,2); + +J_computed = compute_J(A,D,img_i,center_i,window_size_h); +mask = exp(-abs(J_computed-J)/sig); diff --git a/SD-VBS/common/toolbox/toolbox_basic/affine/compute_AD_disp.m b/SD-VBS/common/toolbox/toolbox_basic/affine/compute_AD_disp.m new file mode 100755 index 0000000..f2e6c62 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/affine/compute_AD_disp.m @@ -0,0 +1,103 @@ +function [A,D,mask] =... +compute_AD_disp(img_i,img_j,center_i,center_j,window_size_h,num_iter,w,fig_disp,num_trans,Dest,mask) +% +% function [A,D,mask] = ... +% compute_AD_disp(img_i,img_j,center_i,center_j,window_size_h,num_iter,w, +% fig_disp,mask,num_trans) +% +% Computing affine transform for matching to image patches. Display results +% as program runs. +% +% A: Affine motion; +% D: Displacement; +% +% +% img_i, img_j: the two image(in full size); +% center_i, center_j: the centers of the feature in two images; +% window_size_h: half size of the feature window; +% num_iter: number of iterations; +% w: parameter used in "grad.m" for computing gaussians used for +% gradient estimation; +% fig_disp: figure for display; +% +% num_trans: OPTIONAL, number of translation iteration; +% mask: OPTIONAL, if some area of the square shaped feature window should +% be weighted less; +% + + +% +% Jianbo Shi +% + +if ~exist('mask'), + mask = ones(2*window_size_h+1)'; +end + +if ~exist('Dest'), + Dest = [0,0]; +end + +% set the default num_trans +if ~exist('num_trans'), + num_trans= 3; +end + +% normalize image intensity to the range of 0.0-1.0 +img_i = norm_inten(img_i); +img_j = norm_inten(img_j); + +window_size = 2*window_size_h + 1; +I = carve_it(img_i,center_i,window_size_h); +J = carve_it(img_j,center_j,window_size_h); + +% init. step +D_computed = Dest; +A_computed = eye(2); +J_computed = compute_J(A_computed,D_computed,img_i,center_i,window_size_h); + + + +figure(fig_disp);subplot(1,3,1);imagesc(I);colormap(gray);axis('image'); +subplot(1,3,3);imagesc(J);axis('image'); +drawnow; + +sig = 0.1; + +records = zeros(num_iter,6); +errs = zeros(1,num_iter); + +k = 1; +% iteration +while k <= num_iter, + [A,D] = iter_AD(J_computed,J,mask,w,k,num_trans); + + A_computed = A*A_computed; + D_computed = (A*D_computed')' + D; + + % compute the warped image + J_computed = compute_J(A_computed,D_computed,img_i,center_i,window_size_h); + + % compute the SSD error + errs(k) = sqrt(sum(sum((mask.*(J_computed-J)).^2)))/prod(size(J)) + + % update the mask, discounting possible occlusion region + if (k>num_trans+1), + mask = exp(-abs(J_computed-J)/sig); + end + + % record the A and D + records(k,:) = [reshape(A_computed,1,4),reshape(D_computed,1,2)]; + + figure(fig_disp);subplot(1,3,2);imagesc(J_computed);axis('image'); + title(sprintf('iter:%d: dx=%3.3f, dy = %3.3f',k,D_computed(1),D_computed(2)));drawnow; + + k = k+1; +end + +[tmp,id] = min(errs); +A = reshape(records(id,1:4),2,2); +D = reshape(records(id,5:6),1,2); + +J_computed = compute_J(A,D,img_i,center_i,window_size_h); +mask = exp(-abs(J_computed-J)/sig); diff --git a/SD-VBS/common/toolbox/toolbox_basic/affine/compute_J.m b/SD-VBS/common/toolbox/toolbox_basic/affine/compute_J.m new file mode 100755 index 0000000..80db273 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/affine/compute_J.m @@ -0,0 +1,31 @@ +function [JJ,mask] = compute_J(A,D,I,center,window_size_h) +%% function J = compute_J(A,D,I,center,window_size_h) +% + +[size_y,size_x] = size(I); + +center_x = center(1); +center_y = center(2); + +[XX,YY] = meshgrid(1:size_x,1:size_y); +x = reshape(XX,size_x*size_y,1); +y = reshape(YY,size_x*size_y,1); +index(:,1) = x-center_x; +index(:,2) = y-center_y; + +position_new = A*index'+ [D(1),0;0,D(2)]*ones(2,size_x*size_y); +position_new(1,:) = position_new(1,:)+center_x; +position_new(2,:) = position_new(2,:)+center_y; + +position_new_x = reshape(position_new(1,:),size_y,size_x); +position_new_y = reshape(position_new(2,:),size_y,size_x); + +[J,mask]= m_interp4(I,position_new_x,position_new_y); + +JJ = J(center(2)-window_size_h(2):center(2)+window_size_h(2),... + center(1)-window_size_h(1):center(1)+window_size_h(1)); +mask = mask(center(2)-window_size_h(2):center(2)+window_size_h(2),... + center(1)-window_size_h(1):center(1)+window_size_h(1)); + + + diff --git a/SD-VBS/common/toolbox/toolbox_basic/affine/find_AD.m b/SD-VBS/common/toolbox/toolbox_basic/affine/find_AD.m new file mode 100755 index 0000000..3cccefb --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/affine/find_AD.m @@ -0,0 +1,82 @@ +function [A,D] = find_AD(I,J,mask,w) +% +% [A,D] = find_AD(I,J,mask,w) +% +% find the matrix affine transform A and displacement D, +% such that SSD difference of I(Ax-d)-J(x) is minimized, +% + +% +% Jianbo Shi +% + + +[gy1,gx1] = grad(I,w); +[gy2,gx2] = grad(J,w); + +gx = 0.5*(gx1+gx2); +gy = 0.5*(gy1+gy2); + +[size_y,size_x] = size(I); +[center_y,center_x] = find_center(size_y,size_x); +mask = mask(w+1:size_y-w,w+1:size_x-w); + +[x,y] = meshgrid(1:size_x,1:size_y); +x = x- center_x; +y = y-center_y; + +x = x(w+1:size_y-w,w+1:size_x-w); +y = y(w+1:size_y-w,w+1:size_x-w); + +gx_sqr = gx.*mask.*gx; +gx_gy = gx.*mask.*gy; +gy_sqr = gy.*mask.*gy; + +x_sqr = x.*x; +x_y = x.*y; +y_sqr = y.*y; + +T= zeros(6,6); +T(1,1) = 0.5*trapz(trapz(gx_sqr.*x_sqr)); +T(2,1) = trapz(trapz(gx_gy.*x_y)); +T(3,1) = trapz(trapz(gx_sqr.*x_y)); +T(4,1) = trapz(trapz(gx_gy.*x_sqr)); +T(5,1) = trapz(trapz(gx_sqr.*x)); +T(6,1) = trapz(trapz(gx_gy.*x)); +T(2,2) = 0.5*trapz(trapz(gy_sqr.*y_sqr)); +T(3,2) = trapz(trapz(gx_gy.*y_sqr)); +T(4,2) = trapz(trapz(gy_sqr.*x_y)); +T(5,2) = trapz(trapz(gx_gy.*y)); +T(6,2) = trapz(trapz(gy_sqr.*y)); +T(3,3) = 0.5*trapz(trapz(gx_sqr.*y_sqr)); +T(4,3) = trapz(trapz(gx_gy.*x_y)); +T(5,3) = trapz(trapz(gx_sqr.*y)); +T(6,3) = trapz(trapz(gx_gy.*y)); +T(4,4) = 0.5*trapz(trapz(gy_sqr.*x_sqr)); +T(5,4) = trapz(trapz(gx_gy.*x)); +T(6,4) = trapz(trapz(gy_sqr.*x)); +T(5,5) = 0.5*trapz(trapz(gx_sqr)); +T(6,5) = trapz(trapz(gx_gy)); +T(6,6) = 0.5*trapz(trapz(gy_sqr)); + +T = T+T'; + +J = J(w+1:size_y-w,w+1:size_x-w); +I = I(w+1:size_y-w,w+1:size_x-w); + + +diff = (J-I).*mask; +b(1) = trapz(trapz(diff.*gx.*x)); +b(2) = trapz(trapz(diff.*gy.*y)); +b(3) = trapz(trapz(diff.*gx.*y)); +b(4) = trapz(trapz(diff.*gy.*x)); +b(5) = trapz(trapz(diff.*gx)); +b(6) = trapz(trapz(diff.*gy)); + +a = inv(T)*b'; + +A = [1+a(1), a(3); +a(4),1+a(2)]; + +D= [a(5),a(6)]; + diff --git a/SD-VBS/common/toolbox/toolbox_basic/affine/find_D.m b/SD-VBS/common/toolbox/toolbox_basic/affine/find_D.m new file mode 100755 index 0000000..1e42cb2 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/affine/find_D.m @@ -0,0 +1,65 @@ +function D = find_D(I,J,mask,w) +% +% function D = find_D(I,J,mask,w) +% +% find the vector D such that it minimizes then +% difference between I(Ax-d)-J(x). +% +% mask: the weight matrix, +% w: window size for estimating gradiant, use a large value +% when A,D are large. +% + +% +% NOTE: Because gradient values on the boarder regions of +% I and J can not be computed accuately when using +% a gaussian of large support, those boarder regions +% of width w are not used in computing D. +% + +% +% Jianbo Shi +% + +[gy1,gx1] = grad(I,w); +[gy2,gx2] = grad(J,w); + +gx = 0.5*(gx1+gx2); +gy = 0.5*(gy1+gy2); + +[size_y,size_x] = size(I); +[center_y,center_x] = find_center(size_y,size_x); +mask = mask(w+1:size_y-w,w+1:size_x-w); + +[x,y] = meshgrid(1:size_x,1:size_y); +x = x- center_x; +y = y-center_y; + +x = x(w+1:size_y-w,w+1:size_x-w); +y = y(w+1:size_y-w,w+1:size_x-w); + +gx_sqr = gx.*mask.*gx; +gx_gy = gx.*mask.*gy; +gy_sqr = gy.*mask.*gy; + + +T= zeros(2,2); + +T(1,1) = 0.5*trapz(trapz(gx_sqr)); +T(2,1) = trapz(trapz(gx_gy)); +T(2,2) = 0.5*trapz(trapz(gy_sqr)); + +T = T+T'; + +J = J(w+1:size_y-w,w+1:size_x-w); +I = I(w+1:size_y-w,w+1:size_x-w); + + +diff = (J-I).*mask; +b(1) = trapz(trapz(diff.*gx)); +b(2) = trapz(trapz(diff.*gy)); + +a = inv(T)*b'; + +D= [a(1),a(2)]; + diff --git a/SD-VBS/common/toolbox/toolbox_basic/affine/find_center.m b/SD-VBS/common/toolbox/toolbox_basic/affine/find_center.m new file mode 100755 index 0000000..b12ac7b --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/affine/find_center.m @@ -0,0 +1,4 @@ +function [center_x,center_y] = find_center(size_x,size_y) + +center_x = 0.5*(size_x +1); +center_y = 0.5*(size_y +1); diff --git a/SD-VBS/common/toolbox/toolbox_basic/affine/gen_feature_s.m b/SD-VBS/common/toolbox/toolbox_basic/affine/gen_feature_s.m new file mode 100755 index 0000000..3c113e9 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/affine/gen_feature_s.m @@ -0,0 +1,17 @@ +function I = gen_feature_s(size_of_feature) +% function I = gen_feature(size_of_feature) +% generates a spherical features with size +% of "size_of_feature" +% + +ss = round(0.4*size_of_feature); +[X,Y,II] = hemisphere_s(ss); + +II = abs(II); +II = 1/max(max(II))*II; + +I = zeros(size_of_feature,size_of_feature); + +t = round((size_of_feature-ss)/2); + +I(1+t:1+t+ss,1+t:1+t+ss) = II; diff --git a/SD-VBS/common/toolbox/toolbox_basic/affine/grad.m b/SD-VBS/common/toolbox/toolbox_basic/affine/grad.m new file mode 100755 index 0000000..53bab55 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/affine/grad.m @@ -0,0 +1,24 @@ +% gradient of an image +% coordinates (r, c) follow matrix convention; +% the gaussian is truncated at x = +- tail, and there are samples samples +% inbetween, where samples = hsamples * 2 + 1 + +function[gr,gc] = gradient(image, hsamples) + +tail=4; +samples = hsamples * 2 + 1; + +x = linspace(-tail, tail, samples); +gauss = exp(-x.^2); +n = gauss * ones(samples,1); +gauss = gauss/n; + +gaussderiv = -x.*gauss; +n = -gaussderiv*linspace(1,samples,samples)'; +gaussderiv = gaussderiv/n; + +gr = conv2(conv2(image, gaussderiv','valid'), gauss,'valid'); +gc = conv2(conv2(image, gaussderiv,'valid'), gauss','valid'); + +%gr = conv2(conv2(image, gaussderiv','same'), gauss,'same'); +%gc = conv2(conv2(image, gaussderiv,'same'), gauss','same'); diff --git a/SD-VBS/common/toolbox/toolbox_basic/affine/hemisphere_s.m b/SD-VBS/common/toolbox/toolbox_basic/affine/hemisphere_s.m new file mode 100755 index 0000000..5300183 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/affine/hemisphere_s.m @@ -0,0 +1,27 @@ +function [x,y,z] = hemisphere(r) +%HEMISPHERE Generate sphere and transform from spherical coordinates. +% +% [X,Y,Z] = HEMISPHERE(N) generates three (n+1)-by-(n+1) +% matrices so that SURF(X,Y,Z) produces a sphere. +% +% [X,Y,Z] = HEMISPHERE(R,N) generates three (n+1)-by-(n+1) +% matrices so that SURF(X,Y,Z,R) produces a sphere colored by R +% +% [X,Y,Z] = HEMISPHERE(R,THETA,PHI) converts from spherical coordinates +% to cartesian coordinates. + +% Modified from +% Clay M. Thompson 4-24-91 +% Copyright (c) 1991-92 by the MathWorks, Inc. +% by Carlo Tomasi + +error(nargchk(1,3,nargin)); + +n = r; +% 0 <= theta <= 2*pi and 0 <= phi <= pi/2 +[theta,phi] = meshgrid((pi/n/2)*[-n:2:n],(pi/2/n)*[-n:2:n]); +r = ones(n+1,n+1); + +x = r .* cos(phi) .* sin(theta); +y = r .* sin(phi); +z = r .* cos(phi) .* cos(theta).*phi.*theta; diff --git a/SD-VBS/common/toolbox/toolbox_basic/affine/im.m b/SD-VBS/common/toolbox/toolbox_basic/affine/im.m new file mode 100755 index 0000000..6450120 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/affine/im.m @@ -0,0 +1,3 @@ +function im(I) + +imagesc(I);axis('image');drawnow; \ No newline at end of file diff --git a/SD-VBS/common/toolbox/toolbox_basic/affine/iter_AD.m b/SD-VBS/common/toolbox/toolbox_basic/affine/iter_AD.m new file mode 100755 index 0000000..50bdae1 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/affine/iter_AD.m @@ -0,0 +1,26 @@ +function [A,D] = iter_AD(I,J,mask,w,k,num_trans) +% +% function [A,D] = iter_AD(I,J,mask,w,k,num_trans) +% +% find the affine motion A, and displacement D, +% such that difference between I(Ax-D) and J(x) is minimized. +% If k <= num_trans, only translation is computed. This is useful +% in practice, when translation is relative large. +% +% mask: the weight matrix, +% w: window size for estimating gradiant, use a large value +% when A,D are large. +% + +% +% Jianbo Shi +% + + +if k <= num_trans, + D = find_D(I,J,mask,w); + A = eye(2); +else + [A,D] = find_AD(I,J,mask,w); +end + diff --git a/SD-VBS/common/toolbox/toolbox_basic/affine/m_interp4.m b/SD-VBS/common/toolbox/toolbox_basic/affine/m_interp4.m new file mode 100755 index 0000000..314f140 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/affine/m_interp4.m @@ -0,0 +1,49 @@ +function [F,mask] = m_interp4(z,s,t) +%INTERP4 2-D bilinear data interpolation. +% ZI = INTERP4(Z,XI,YI) assumes X = 1:N and Y = 1:M, where +% [M,N] = SIZE(Z). +% +% Copyright (c) 1984-93 by The MathWorks, Inc. +% Clay M. Thompson 4-26-91, revised 7-3-91, 3-22-93 by CMT. +% +% modified to + + +[nrows,ncols] = size(z); + + +if any(size(z)<[3 3]), error('Z must be at least 3-by-3.'); end +if size(s)~=size(t), error('XI and YI must be the same size.'); end + +% Check for out of range values of s and set to 1 +sout = find((s<1)|(s>ncols)); +if length(sout)>0, s(sout) = ones(size(sout)); end + +% Check for out of range values of t and set to 1 +tout = find((t<1)|(t>nrows)); +if length(tout)>0, t(tout) = ones(size(tout)); end + +% Matrix element indexing +ndx = floor(t)+floor(s-1)*nrows; + +% Compute intepolation parameters, check for boundary value. +d = find(s==ncols); +s(:) = (s - floor(s)); +if length(d)>0, s(d) = s(d)+1; ndx(d) = ndx(d)-nrows; end + +% Compute intepolation parameters, check for boundary value. +d = find(t==nrows); +t(:) = (t - floor(t)); +if length(d)>0, t(d) = t(d)+1; ndx(d) = ndx(d)-1; end +d = []; + +% Now interpolate, reuse u and v to save memory. +F = ( z(ndx).*(1-t) + z(ndx+1).*t ).*(1-s) + ... + ( z(ndx+nrows).*(1-t) + z(ndx+(nrows+1)).*t ).*s; + +mask = ones(size(z)); + +% Now set out of range values to zeros. +if length(sout)>0, F(sout) = zeros(size(sout));mask(sout)=zeros(size(sout));end +if length(tout)>0, F(tout) = zeros(size(tout));mask(tout)=zeros(size(tout));end + diff --git a/SD-VBS/common/toolbox/toolbox_basic/affine/norm_inten.m b/SD-VBS/common/toolbox/toolbox_basic/affine/norm_inten.m new file mode 100755 index 0000000..8e8865b --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/affine/norm_inten.m @@ -0,0 +1,11 @@ +function I = norm_inten(J) +% +% I = norm_inten(J) +% +% normalize image intensity to the range of 0.0-1.0 +% + +max_J = max(max(J)); +min_J = min(min(J)); + +I = (J-min_J)/(max_J-min_J); diff --git a/SD-VBS/common/toolbox/toolbox_basic/affine/pan.0.pgm b/SD-VBS/common/toolbox/toolbox_basic/affine/pan.0.pgm new file mode 100755 index 0000000..2e7b5f6 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/affine/pan.0.pgm @@ -0,0 +1,53 @@ +P5 +# CREATOR: XV Version 3.10a Rev: 12/29/94 +128 96 +255 +qquvvvvwzyz{}~€‚‚‚ƒ„††…†‡ˆˆŠŠŽŒŽ‘’“•–”–——›œž ¡ ­©¤¢£¥¥¥¥§¥§©««¬­°±²²¶¶µ´³²´³³¶¹»ÀÀ¿ÁÃÄÂÄÄÃÄÃÅÆÊÇÆÆÅÊÉÈÊÏÞËÄÃÄÂÂÃÃÀÁ»qrrsvxwxyzzz{{|~~€‚ƒƒ…………†‡†‡ˆ‰ŠŒŽŽŽ‘’’“”•–•“•˜™šœœŸŸŸ¡¡Ÿª°¥¤¦§¥©«ªªª«¬­®°³´¶¶¹·¶··¸¸¹¹º½½¾¿»¼¿ÀÀÂÂÃÈÇÈÊËÉÈÊÊËÎÍÉØ×ÈÆÄÄÃÅÅÃÂÃÀtuwuruzzyzz{}}}‚„„„†‡‡‰‰‰‰‹‹‘”’’““•—–˜——™š›žžŸŸ¡¤¥¦¤¦·¬§¨©ª¬ª­¬­¯¯²³³¶·¹¹¹½¼½½¼¼¼¾¿ÀÁÃÃÁÄÄÃÆÇÇÈÉÊÉÉÊÊÎÍËËÌËÍÞÌÂÄÂÂÃÅÅÃÁÃÂtvwxyxwwz{{z|{|}‚„„…‡ˆˆ‰‰Š‹‹Œ‘‘’“•—˜˜™™š›œžžž ¢¢¡¢£¢±º¬©ªª«¬®®®°³´µ¸¹¹¹»¿¾¾½¾¾¾½¿¿ÂÂÁÀÀ¿¿¿ÂÆÈËÎÒÔÖ×ÖÔÓÐÎÎÎßâÒÕØÜááááàÜÙÕtvwwyz{ywz}}‚‚ƒ†‰‰ˆˆ‡‡ˆŒ‘“”’“–—˜™š™šš›œœ›œžœœž Ÿ š ´œ•™š¡¥¨¬®®®­­­ª©ªª­¬ª¨¦¥¢ÇÕÃÄÅÅÅÇÅÅÅÂÅÆÇÇÊËËÍÊÍÐÐÑÐÑâÖÓÓÔÖ×Ô×ÖÖ××Ðm„zuuvvvurvuwxz{{{}€ƒ„ƒ„††‡‰Šˆ‰ŠŒŽ“•™šœœ›œžž¡¢££¤¤¦¦©¨§¨§µ³¢¦ª®±³®¢žžžŸŸŸŸ ¤§©©ªª§ËÚÁÁÀÂÅÄÅÇÆÇËÍÎÏÐÏÍÏÑÒÔ×ÙÙãèÝÛÜÝÜÛÛÝÚØÙØÓBUw…xz}~}~{{€€‚„„ƒ…‡†ˆ‡Š‹‹Ž‘“”““•—˜˜š›Ÿ¡ Ÿ¢¤¦¦§¦ªª«®®±Á®­­±³µ°¡šš™š™™›¡¥§¨©«¥ÃàÈÇÊÎÍËÎÐÑÒÔÖÖÕØÖÖÚÞàáãâáîéâæåçéåâÞàâààÝGcZW„}}~}~ƒƒ„…„†‰‰‰‹‹‹‘‘’’’“••–—˜œŸŸžŸ ¡££¥¨§§ªª«®°°°¯ÅÀ¨­³·µ­ š¡¢¡  ŸŸ ¤ª«­¯¨ÄèÑÏÑÓÔרØ×ÛßÞßââãæéêêêêéíòéëììîíëíîïïííêGeoxae“~€‚‚ƒ~„ˆ‡‰‰ˆ‰‰‹Š’“”—šššœ ¡¢¡¡£¥¦¦¦¨¬­®¯®¯°²²²²³´»Î·°¸¹µ­¥ œš›œœž¢¦ª¬®®²¸²ÇëØ×××ÝàáåæéêìëïîìïîðððóóöôðñóôóôôööõõóòîFakswvey‚ƒ„……„€ƒˆ‰Š‹‹ŒŒ‘‘’”•–˜˜™š›Ÿ ¢£¥¨©ª¬¬¬®°°³´µ¹ºº½¾ÁÁ¿ÊÓº¿Ã¹±«¥§­±²±®©©­±´²³´±ËñáßáãæèìðòõõõöøùøõîæßØÏÓõðïñóõ÷ùõôöîëççïIbjnpu|x_‹Ž„††‡‰ˆ„‰Ž‘‘’”–———›œž ¢¤¥§ª©ª¬®¯°²¯®³´µ³²´¸º¼¿ÅÎâ¡nbb_eq†¦Â¿Ìå÷ýýýýýüüüüýýýýþþþþþþþþýýýýüüüüçæ¼­®ã–½øúú§>¸áq±}̶Gbjkloqw|pn‹rcbbehq…‡ˆ‰‹Ž‘’”•–ššœžŸ¢¤¦©ª«®°¥Œ› “ »ÂÄÅÅÆÊÍÏÓ×ÙÜç«Õûúúü÷‹.ÃýýýýýýýüüøíüýÚÞîØüÝÈþþ«¨î–Ù»“ô臞‰fšb€’Žf0^xF_VYqH^ehkoopqy€f†ðþþþûä‹|”–˜–‹“¢£ ŸŸŸ¢¤§¨ª¬²±°°x;33>AV¨ËÐÒ×ÞáÌÆçñúã•ÄyÂýýýÉi5!q¸¬ŽcMi<2<3WWB=XFoZMqeHNtMdfV„wNi…v\uat}ˆŽc*dHY]ZtG]aced`C233++%)(*59:@7B>F>FEA=<\g^gb\^Ya][\PD83.2X_=Hj?42)Wh3%GkgpD8€…€xb`vJQjFktVR|LvtTytLU{OdoU…}N]‡sSwZl‚Š‘[+e€IVYRqI[^___W?519+&'112>;9G<@;E8BG<:5V[FYYLPIHHMA4=A83:PMd{m@BdmUOi?$ByC!'Q_pS$l„‚|hSrJMqG^ugp‡Os~Rq|QRN\wM}€SYŒyQuPe‡’X#_€NQ_RpFX\]^YK512:)&(032>?9B=E:G7AJ@B;W\GRWHOHEJIB5>C@:4NQ^xp<5[njF€lJ, %pIQk]L*&X€w{qReNBnIGe’Ô¨Yj‡KayPR€XQ€Qu‚XQOtUb‰Ž”^%[QPcRoGUY]YNC445=)%+.01?98EAG=E6>H@B7BFRwvN\r>itK2WRJmRZ9(AepvPZ[BpVCf‡Î¨U]ŠN[zSKgU‡Pj‰bJ‘QpX\‹Ž”d%U…VPhNmFUYYTG>26;?*'+247><;HCM@I7<J@H:;JAF>O[SM_PR]XVLSJ8>8565BD_v>)hiEwU-"lLGpcaHA$U~o~wRjLJrCCZ†ŒuDtsF}yPq„SmlT…MsY`tZŒŽ“~2CƒeMrRqIRSMGMXPF>A.**0.APIR>L?9K;DEQ]XP`VS]\[OML5?C8?7BDX|~R[sBm‚_7[_"=cqfj_W;Is|~T\[HvRCa^DxGj…HqPg…W\yX‰ŠSe”e^ZŠ•„9@„kLrPmGOOIM[\MC>@+(*-,7>;GAJYUU_ZU^ZOKGP?IH2?5>GRu€e&KuK]”gH#DoNXhj]FE]jb|rvZRmIp_?fbCxV[‘NdƒQ\…[U…Qy‹W`”o[Š\‚‘”ˆA<qNvPmHOKFM[\NB>?)(,,+>BBDSHP@FA8ICG@F\WV]bS_\KLISOED2:4:FNpˆt85teTœhQ+*ENWOG6*+;PVm|x…kPpK`pVp–zuoZ–YW…_Z‹hP…PmŽ`[•{[“\}‘—ŽL;~wSvQiFIHDLXVJ@<>(''+)7AEESGO4*))(ATq~†„Q[VIt<6:RTq}U‚VV|a^˜x]^af‘–“V+nOoS]EFEELOB/&5?ABREK=CI;KLIH=b_\YVPMT[cZVVGDA4<6>BT}‡m+N|\[šf/"$');GGC7,%2W]l€ƒ^UhHk:+DE‡Z`ŽWw†Tr‡Vmn]˜ƒXŠ”byeb”•–\%h†QlV]GGHDJL;+.%%1'1-!?L@GMIN@\aYTVVQWgaWPMKIC1:6<€pY‚;%%"&/BPF<>9* ,NUVzƒmV{GW5 #FBuhZUj‹\c‹XiX“‹W}•epmc–•—c(^†Pf[[EEFDJH4$&(COEZsW.Q=GQDR:V]U^]`_`\^[M]VOI8868CIfˆ‰_!a‚_.')/3:1-35.+)#,DPFcƒƒbdY:1,;M[ŠXv\m\‹k[”\~•Wo˜pg‚a“–s(TŠUafUBCGBF:&&""$.ReV4 8A?NHDJ>O>DPISAP][dcb[ZSZfX`QBH?37/AD\„u0F~T.31./:?:'9DBGJW}…dVj@5"3@XXŒWo„^Ž}_…xY[n™bjžyjŒdŽ”—|+RŠ[ZlWDFGDA3+,!12'6FDIKJO>RBGUMUCQdcjfaWWT^gZXYFHK291K‰hZuWHGDDE.#  +!"9HGJOLUCPEHRKMFJaf`XW^_e`^aUa^KI5:.,FLkd$I#:WRQXXiy|wz‹s;1/]ƒaf]%! DuZg…\˜g`ŒWhŒ_i}e™‚c¡Žje|—˜’EDiXzVEGFDC1-)%0ZdH')3;=HGEMKVBQJJTJNHHfc`WOjg_X]dXabOK674+EId‹p6 +!Njv„†„}}‚›v>-"S~ƒvŠ‚zˆ{šc…sbŽb`ˆfd„g˜a“o‹hx–••XA€s\[GFFFC/44,-ZkL+*0=AGFCILUHQLJPAMHA^ZX[OkcVXdfYX]LLA3:1>K^‡“„C $Tgmt{vuz{}‡”–|>%R|ž¦¦©¨«­¯²©pn‚hŠs^ˆqb‰m‹’Zz”kfr–“”]AOUaga^bcehnppprvvvtw{xz{x~€ƒƒ„‚„‡‡‡‰‰‡ŠŠŠ‹Œ‘”šœ˜’v)+UL>516HZU?8?QhsE!cª¯°®¯®¯°²±²²²´³´´³³³´µ³²µ³´µ±°±¯±°¯¯®®­««¬«ªFFIL[bcfjlnoqruwyyz|~~}}„€€€€€€„……ƒƒƒƒ„………„‚ƒƒ‚ƒ„ƒ‚‚‚€‚zE:\?+)69:“|=.0BTx^28^nmkijiiijfffdbcb`aa`_]^^``_\\\\]^`__a`b`bdb_GHJM[XPNOQTTVVWYZZ[[\\^]]^_`aabbbbbbcdfgfggghikllmoppqqrqqrrsrB>eSLIE:[²˜C2,94>BB.7AB11< '' +"5 $EXg€‘Œ~p€š©¤•ˆ|W5((..!!%GHN)   5*U{`_uH\h_xfDt|~Ngk!  /t_$$&T¬’={ž@^ÇÈÊËz @U\iux†’’‚xzx—s3Z”s-AµËyj«´­ÄÁÛvO@2RRIQMx™“xst¢ž–Œ‚¦¬~KNNNOO_WesG_jbx‚fHw}Nnj   +5|]$##Z²’?—?bËÊÎÍpQdPY`inr}‡„|u}e¨š7V”u%OÀÏvl§¶¿»Ëz8HwgMeZƒ˜•xvr„£›•£¥•Œ¤¢rLNNNVgjYgvKegcy„gJx}~Qsi   !#3_O#>EL™¥­§\cOONWWRT]kqkozdÀ¯:1><"2LTSq«·¹ÐÙÀgM=FNHFIUŽ£‘qrq‰¥œ‘ œ–Ž–£œpOPRRdmkXfuQjhg~ˆjLzPxf + + +#&!]½mOKIOY_badin\‚ùø¨G:6$WZb§ÇÇܬNRJDKB>Bg›¨qvv•­–˜« •—œ¥oMNQVgolUiv[sdc€‰qN}ƒ€S|b  +  +%%Ÿôêۼ׎GOPMKQ\\SSÖøùûûûûûû¸=&FX[f€¦ÍÉá¶\KWZOUOF|ª­‰uzz£­”¡¨›™œ¥¨~tMPRXjqlJb|e{eby†zV~„|[†\ +   + !$' ÷ôãäóòص»¢nILJG;q¦Vªöüüüû÷úûûúúúÉfqœ²kCY‚aDGZbOVWQ“²©†zƒ¬°˜©¦ž›¡ª§wzKMPXinkC[}awhbˆ|Y‡|\‡Z +    $%>¬ôüüôèæôõë·—\{€S@F‡•b„å÷üüüûôõûûúúúúûç¾¥lY\Z<=5czK^nb³¥{}†­©–­®§Ÿ¢§ t{KMQXjojFW€fyqf„Œ…`‡|_ŽY  +  '& KåôøüüüôêçôöôØžh]j7PŠwO|w©¸¤~€‚´ª˜¬­ª¢¡¨›pzLNOZloh>N‚csyh††[|‰}aY    %&NÐýûùüüüüôîìôööï·œˆexh´òú¿Îüýüüüûøùûûúúù÷úûûûôôôºG?5Lp^;^zµ·˜s€~•À« µ³­©««‘qwLMOZloh>F…cpƒm†’c~‹€b”_   '%8Ìûøøöõ÷÷÷÷÷ïï÷õõõ鼸ª—åúìãÊ÷úüüüüùùúúýýýóóûûûýýý§9>~p^”k}—žbz‘’\ˆw! +  )' Ÿûûûøøóð÷÷÷÷÷óîõõõõõåÖñòýýýýõéôúüüüûöøúúýýüòôûûúûúúÈxŒf\WVIH”ÅÇŒz…|²Ï´´¿º²«²³{…kMOOZoqhE9~`pwšžbv’•a€|*  + ()aÚäêûøøóðö÷÷÷÷óïõõõõõïÙîøýýýýøõ÷úüüüû÷÷úúýýõçóûúøýøú÷Ã`‰µ“›´£ÂÊ|„³É°¸Ã½µ°´¬q‚bNNP^ppiC0{a„yu¡jq“™l…4 % +"*(ÙÚØñùùöõöööö÷ôòöööööêÜîõúúúúùö÷ùûûûûøøûûüüùëñøóñýêòûÕgaG]uV­Á¸‚‚‡‹ÀÅ­ºÇù¶º¦q‚SMNQ^qohI&jYfˆu•œqd“—szˆ6 + ! !)+ >ÌïáÒßùù÷òôööö÷ôóöööööïçïôúúúúøõ÷ùûûûû÷÷ûûüüûêñøîïýòîöÑS‡Å_˜¨s¾Â²{†ŠÁ¿£¼ÈÁ¸µ´–p~JMMO_wwpcVapXWkWr{OKƒ‘fpk' $!#..!^ÄóáÈÙùùùóóööö÷õñõööööòëðõúúúúøö÷ùûûûûøøûûüüûðôøíñýðèñáef}rWh„ÅÂ¥x†„’¸¤ÅÅ¿¸·²‘x{DKOQbrrtwy|€„ˆ‹’“–——™œ¡¤¥¨ª«ª«ª©¨§¨¨¥£¡£¡žš”¥»ìéÂÑøù÷ìîööö÷ôðôööööôïïî÷úúúôñ÷ùûûûû÷÷ûûüü÷ëóøööýûáßû„GNBF7s»±‰gkwšÅ­¨Â¼·´¥†s?MPRYF997:<><>>><<;;:<AEINS[aflqtx}v¹Í½ÉÄÖÅìøõéï÷÷÷÷ôäïööööõéãìøøøùíî÷øúúúúùúûûûûûù÷ôÁãú÷ÙåýýëÌÈÈÈÇÇÆÇÇÆÆÅÄÃÁÁÀ¾½¾»º¸¸¶ILLMB$ LÒâÎØÝÔ²æøøíî÷÷÷õòæî÷÷÷÷öïàòøøøøëéøøúúú÷÷ûûû÷÷÷÷ûôºåðåØñýý÷žƒƒˆ‹”˜žŸ£¦ª®°³´·¹»½¿Á¿IKKJD-  TÐæÕÐä×¶Ù÷÷êé÷÷÷õóæë÷÷÷÷öðäîøøøøéå÷øúúúôóùûû÷÷÷÷úùÜçßÖÑ÷ýýý“#&$# ! !  !!JKLIF7  PÐóèÎßÓ»Ööøîî÷÷÷õõêç÷÷÷÷öïàîøøøøòîøøúúúòíùûû÷÷÷òùòÎÕÕÔàýýýýÎC&$#"  !""!"""!"#"%$EJLHC;' ]ÔöñÔÚñÖõøñð÷÷÷õõéç÷÷÷÷öíÝðøøø÷îìøøúúúðç÷ûû÷÷õéïðÙÈÍÖáüýýýõw%&%##"!#"!"#"#""""#$$&'IJIHF?. uÚùôÜØÂ›Çôøòíöøøõõëæ÷÷÷÷øîÌéøøø÷íð÷÷úúúïÝöýýúú÷ìòàľÒÜàöüüüü¨2)&$"#$#!"""#"#&%%&)(()HJKGDA7$  &‹ØùöâÖÆ¯ÅñøóæôøøõõçÞõ÷÷÷÷êÞöøøøöëñ÷÷úúúïÞóøýúúôÞïß²«Óß×èüüüüâW,(%%%$"#$####$&&()(+.0GHJJHB=, @¯áùøé×À¥¸êøóéôøøõóåÅë÷÷ôðæÜóøøøöéï÷÷úúúèÙ÷ýýúúõàò衤Üèßäüüüüú‡$('''%%&''&%&&'(),*,/2FGFGEB?2 [ÌëùùïÔ¯œ¤Üòñçôøøòïã¿ßóòìßÝòøøøøòåñ÷÷øöö×âýýýúúñßôâÖðêàúüüüúÀ9-))('%'''&&((+---.022GHHGFB?7& oÜóøùíϦœ—ÍëïêöøöóïÛ»ÛïðæÛäöøùùùõåóûûüüûæíùùùûûèÑéÊ™©ÔöóÖêûûûüîn+++(()'&%&'*+--.04333FFFGFB?9*~Ýó÷ùó×§¤œÂÙáØòøõðëÖ·ÑëçÞßðö÷ùùùôäöûûüûéÈçùùùûùÔ×õ§°ËùñØêûûûüüŸ.-+*((')()+,-./013444FGJIGDA;0  "—âùùùõݵ±£ÁÖÑÎóøöïêâÃËæÞÕäñóôùùùïÞ÷ûûüûêÐëùùùûùäîð³·½ÚùùÜãûûûüüÛS5/++,+++-/./10362251DGGGEB@<4& B»ñ÷óôõÒ°³¢¹ËÊ´àøôâÔÖÁÆáââðêðòøùùïÛ÷ûûüüïÜóùùùùóØîâ¡¶ÛõùùíÛóûûüüü…)-.,,+*,.00122244444FFEEDA@=8- _Öôôíëôླྀ£´À±ÇÞÖÍÏÒźÔÜêóáìòùùùïÖòøøüüìëûûûúøèØõÑ›´à÷ùúõÞêúúûûû¹60,,-.../0334555553/BBDDCB?;6." yÐéèæÞÝìܵ›°À̹ÀÚÞÔÊÒǹÑàïðâîñòñ÷íÙõøøüüíéúûúúúçÛøÄ‘µæöùùöàáøúûûûîn-.-/../112333335421EDDEB@?<80% 6–á÷÷÷öèÃÓÑ•¨¸ÆÂÀÚÏÈÈÑIJÌäòíÛëóùùùíÚôøøüøàãûûûú÷ÔÙú¿Œ¶èøúúúèÌéúûûûû¥6.,/121134464543244ADECAA?<93' N—Ñö÷÷÷øëÖⲫ½ÈĹÒÓÍÐØÌ¬ÉëôçØîò÷õöÜÐôøøüôÓâúúúùïÓãô¸‰©ÑôùúúïÙìúûùùûßZ20012/233121132122@?B@A?A=:4+!d‡†ÏÍ·¼¼œ¥½®¬ÂÌȵÈÒО¿¨ÁæòãÕïñö÷÷ãÃñøøüöÑåùûöôïÜìö°˜¹ñøðíñæàýýýýû™/44314442034532441BABBCB@><82& ‚ÆÞô÷õÑ™”˜†˜³ÂĬ´³›‘Ÿ««¾ëòáÏßðòò÷îËîøøüøÔàø÷ðøîÝíö¤}Ÿ°äêæçîõòûýýýýúÐQ84443444222333121>@CDDCB?<93(DÀúÝ÷÷÷ùúÝŠb‚¯¬™‹“§n‚ž®ÃìòáÓêð÷÷öíËáøøüüÝäüüûûöàìç€t¡¸¼áúúýúìöýýýýû÷…88432421255422122=>@AABA@<94+"nݱ³Ùô÷캙”™vkwwy„œ¯¢yWp’¥ÐòÜÍéò÷÷õçÈØôøüøæîñìêéæÍæævp›±òúúúýý÷öüýð½‹U973222122233220252@AABCB@><97.#(®rH 9ltvpmb\ZZr™³¢T !&¡ËÊñòìô÷ïÎÓïöýîÞíåàëìçÊëÞnkœ¥ÖúúúûÝs2.BS@78423322312311221/11>@ABABA=<;72'(0&;_ggea\SQU]i™¯žSˆÆÌÝæôõõíÎÏëöýùè÷üûúûöâñÖfl–¡ÆÅV7@CDK<3443223322334443233110=>CCBBAB@<94)!  ""!!"""##%"#&'!(AW^_``\XY^XWb‚Ÿ“P%¤µÈñøöøøðÐÍáôýýýýüüûùôæñÒxmŒ—€Z8:>FNI:899:7878557677766777554>?@BABB@?<95. !!"""##$%%##$%%&((''(-5@LSWYXVTRKDI^`hz`5*, /“©´øüøøøóÑÑßðüýüüüüüøíÛîÎuaƒ‹X=;=DOYI889:9::999879::999:98886 \ No newline at end of file diff --git a/SD-VBS/common/toolbox/toolbox_basic/affine/pan.1.pgm b/SD-VBS/common/toolbox/toolbox_basic/affine/pan.1.pgm new file mode 100755 index 0000000..9d57f70 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/affine/pan.1.pgm @@ -0,0 +1,59 @@ +P5 +# CREATOR: XV Version 3.10a Rev: 12/29/94 +128 96 +255 +prsrxxwxz{{||||}~~‚‚‚„ƒ„…ˆ‡‰‰‰ŠŠŠ‹‘’’’””–™ššœžœœžž¡ «§££¤¦¦§¨¨§¨««¬¬«¯°±³µ·µ³´´µ´·¸¹¼¿¾¿ÂÅÄÄÄÄÂÂÃÃÄÉÈÇÆÆÈÊÈÈÌØÅ¿Ã¿À¿¾¸prsttuyxyyz{|{{|~ƒƒƒ„†…††‡‡‰‰Š‰ŒŽŽ‘‘’“’“””“—ššš›žŸŸ¡¢¢Ÿ«®£¤¤§§¨©««¬­®­¯°°°µ·¹¸·¸¸¹¸¶º»½¾¾¿»¼¾¿ÀÀÂÄÇÇÇÊËËÉÊÊÊÌÌÉרÇÅÂÁÀÂÁÀ¼tuuuwwvwyxzz{|}€€ƒ‚„†‡ˆˆŠ‹‹ŒŽŒ’’’”•–•˜”•š›™šŸž¢££¤£¦·ª¨©©ªªª­¬®°­²²±³¶¹¹¹¾½½¿¼¼¼ÀÃÂÂÂÁÃÃÆÄÄÅÆÇÊÉÆÇÊÈËÍÌËÊÊÆÚÊÀÀ¿¿¾ÁÀ¿¼tuwwxxzyy{{{{||}~ƒ†…„†‡ˆ‰ŠŠŒŽŽ‘““••”•–—˜™šœœžŸŸŸ  ¢£££¥¡°¹¬ª«ª¬®®­¯±³µµ···º¼¾¾¿½¼½¾¿¿¿ÃÁÁÀ¿À¿ÁÄÇËÍÓÖÖ×ÖÕÔÒÑÑÑÏÞäÕÖÖÙÛØÕÓÒËuvuwyyz{~{z~~~€€‚ƒ……†ˆ‰‰ˆ‡ŠŠ‹Œ“••—˜˜š›œ›œœœŸŸŸŸ  ¡¡¡Ÿ››¡³œ—˜œ¢£¦ª®­­¯¬¬¬ª¨©«ª©§¦¥¥ÌÕÄÃÁÂÅÉÅÄÆÃÅÇÊÊÍÍÌÎÊÍÎÏÑÑÓâ×ÕÔÓÕ×ÓÔÖÕÏ_`k€{x{{zzywzyz{{{}~~€‚„……†††‡‡‰‰‰ŠŠ‹“•™šœžŸ¡¢££¤¥¦§©¨©ª¦¶µ£§©®³µ®£œœžžŸŸŸ¡£¦©¨«¬ªÎÚÁÂÁÂÅÅÇÈÈÇËÍÏÏÐÍÍÑÒÓÕרÙâèÞÜÛÜÜÛÚÚרÕ8:E[‡{|€‚‚}…„ƒ„…‡…‡‰‰‹ŒŒŽŽ’’’””˜˜˜˜š›Ÿ  £Ÿ¢¤¨§¨ªªª«¬­­¾¬­®±µµ¯¢™™šš›››œ›Ÿ¤¨¨©¬§ÆâÊÇÌÎÌÊÍÐÒÒÒÕÕÕÕÔÕÛÝáááááïæâäãäåãàßááÛ57@_WY…„€€‚‚€ƒƒ……‡ˆˆˆŠŒŒŒ‘‘’“”•––™šžž   ¡¡¢£¥§¨¨ª««­¯¯²±Ä¿¨­´·´­¢š¢¡ ¡ŸžŸ £ª¬­°©ÅéÑÏÑÓÓ×ØØØÛÞÞàäããåèèèëéèìóéèééëìêìííîê:9D`ny_i”ƒ€‚ƒ†‚‡‰‡‡‡Š‹Š‰‹ŒŽŽŽ‘’“•–™™™›œž ¡¤¤£¥§¨©©®¯°¯®±³´³³´µ¾Î´¯·¹³®¨ ›žŸžŸ¡¦¬¯°¯´¸°ÈëÖØÙÙßßàèèëìëëïííññðððòîïôòôóôóõöö÷öóí8:B^kryxc}„……††ˆ„†ŠŠ‹ŒŒŽ‘‘’••˜˜˜™š›Ÿ¡£¦§©«­¬¬­°±³´¶»½½¿¿¿Á¼ÈÑ·¿Â¸°¬§¨¯³³²¯¨ª®±´³´´¯ÇïÜÜßâæéìòôôöøøøøøóìæâÜÒÉ÷õóô÷ø÷÷îëôÝÛÚ8;C[gorv}wb‘…ˆŠŠ‹ˆ†‹Ž‘’“““’”——˜š›žŸ¡£¤¤¦ª«­°±²²²´²³·¸·µ¶¹»¹½ÄÊà ned_gx­ÇÊÙñüýýýüüüüüüüüþþþþýýýýýýýýüüüüûûÕÑÀ®¥ß·øúø¥0­çmšt9;D^iloquz~nq’xifdefq€„…ˆŠ‹’“•—˜™›Ÿ¡¢¦§§ª­°ª’Ÿ¥—¤½ÂÄÅÆÉËÍÐÓØÙÜç¨Õûûûü÷†1ÅýýýýýüüüüõèûüÚÞíÕûÛÀüýª¦ï‘ͺŒäØx—„^Ž[r‚‡ˆk4\|JSZ87A[gjknqtw{€f”öýýýû䀔–˜”•œŸžž ¢¡£¨¨«­°¯°°y962??XªÉÏÑÔÛßÍÇîñúà•ÁvÃøøüÃb0 n® ’WGa7-84Z`HA`Hu_NulKQwIaiTƒxNc‡w]uZm|‡i&[~KQ_8:BZdeffcK5850)%)09::B6BAIAGIEB>]linhbc[e_^aRC71/4=Eera?=Y_=He<30(Wd0$FkenD9„y_]wKQlImuVS|LvvSvrKT{MbqSƒ|R[ŠvSvUb€‰]$\KM`;;CX`cba[A2/41)&2-/=74CC8H8?H?EUYVQF>7:>A,%(2-6A:;N@KBL:7L?G@UYJ@XEMQP\GTF@@4:58EHh}m/ 6nXOmG*3q<S{jJ$)&lwqnUvG[n>FU™hJƒcLƒqV|ƒStbW…MzTcoY‹Œ’~3C‚iLq??ESURJA=46A+)*+*7>>>LEL>I?7G+,,0+<>>ES@KDGC;GBHBF^^X]aP[WEKBRNGC0969GKo„q45teWjJERTOC3,7O_K*#h}{‡oRqJanUi†rwqW—]U„`WkR†Qne[–…Z]sŽ”T1t~PrACEJIFKYWLB>>'#(-*8>>@REM) + &':=@CSDJ>GHUC/ Gˆ~„ƒPZWIr:37Q“SnV}V~Tyf_˜{\”b|ca•”•\&a‚MeACEHGELUF6&6<@BREH;?KcaYUSNLRX`YWUEDB4;7?EVˆm*O{P'$&)8DIG;.'.S[E'2}„^RiGh:*ED„[^Vt†To‡Tjr\–…V‚•cqj`’“•b"[‡Oa?CHIGELQ?/1) -#+'&7=DTHI==L>GOFO=^\WRPUSYd^PKIHHC062;EP{‹}7 +=S*# (>RG9?9/ @VJ3'j~~ƒmUyGX1!FCujYŽUf†ZaXgƒYŽVz“ffub”•—k'UˆR]ACDEFFKL8'&#@UERnX-9BCNEDC=L=FPFL:X\RRSZYc]]YKPPOI3616CLn‰ƒL".),*-8A@;53/*%$8HH;R„}„~YmLC/#;Ec~YŒa[ˆ`[‰b\ŽY‚Vp˜mgc““—r%RˆWXCCEFHFKG-+OA3;t„n98@@QFEJAS?GRGR:S`W]\_b`W[[P]VNH8845BIf…ˆ`" #&+/40/78/,+%!8NE>#B„„‚^aW;2.9NY‹W~v]q^ˆq^•Ys•^lui‡dŽ–˜{+O†_UACEEFCE>''')',JeZ=!7AQ@EPEP?P^Ycdc]WOXd\cSDG>46.CF[„s4!!,42-.7;8)-EKEP@THIULTAMbajebUUV`h[XUFIN2;-;FW}‘F%(4HPH=blQ49:1$f}w‡uZrF%.MjX€ee˜^‡^{]hc›ul¥…hf†“•‰?G„lVBDDEHFC1(- +)2%0@DEKHS>SFIUFLCHachZYXW`fbUOYPUO19*2GPu„B'8Od`Ue€l<)51U†zƒ}`qN&QuTpwaœaoŠYm]tr`f¡i’e~”—’EAƒqWEEGIHEG0! +#"6FEHQKTEQDERKMDEae^UR^^d\V[P`^KI3IIFOLU@NIHTKKDCe_ZTMkg\UXcW^^JH6:6+DGbЉ<@es€…††€~‚žŸ“|I0*3.2y}ƒs‡Œ…„|ˆ‚z›a„ue‘eaŠe_ˆh•’`Œ—k„hr–”—]:z}YFEFIIJI323()UkO*(.9AIDBKGOCNJKRCNHA^UT[Jg`WVbdZV[JNA5<0>I\†.Ehpx}yxz{‹™£ž„I'!,$#g~‚z£¦«¬®¬©®¥nl„gŠt[†qcŠh€Yu™fwii””i;oYEGIKLIPI;:GM[c^X[]acgklmmqpoqswuvwt{zy}z€‚†………‡†ˆ‡‰‹Œ’›“BKSG<69G[ZI@EUlwT(I¦±¯¯±²°®®®°±±±¯¯°²´µ¶µµ´³²±±³³±²°°¯¯°¯¯®­¬¬ªª§FEFILMYgiikoprvwy}€}‚……†…†„…††…††‡†‡‡ˆ††‡‡‡‰‰‰ˆŠˆ‡‡‡ˆ‰ˆ†…„ƒY-UM2)-88{}B/'8Xsi4(Imnnmnmlhhigeccecb__`a^^\^]\\\]^]]][\^^``bbceebFGGJLLZYOMNOOQRTTSUVYYYZ[[\\^^___^^^`abbcegffffgijiknnnonooqY(2`TGCA=K¦©K9>V_xwHPo…†ˆ‰‰‰‹‹ŽŽŽ“’’““•••———™˜—˜™™˜™š›šš™š›š˜HIJMMN^lqopqrsuwzz}ƒ‚‚„†‰ŒŒŒŽŽ‘’“”””““”–••–˜››œ›œœšn4Ajymeiƒœ¨†`_v“žM@‚¦©©ªªª¬«­¬¬­®®«¬¯­®®®®°°¯­¬®®®®­ªª©¨©¨©©ªªª©¨§FGHJKKZghgilnoruwwz|}~‚ƒ‚ƒ„………………†‡ˆ‰ˆˆ‰Š‹ŒŽŽŽŽŽŽ~M;aŠ—˜¡­¬«š­º¨wWj‚ŠŠ‰ˆ‰ˆˆ‡……‚ƒ„ƒ‚€€~}|{yxwvtrpomlkhffebaaa_\[YWTKMMLNMK8" +  + + + + + + + + +  +  ,?Qt‰œ§š†˜ž·»´«”taA!!"$&%$&'''&(&'&'(&%%#%$"$$%#!"##"HKKJJKI?+    + +     + +ASd|“ ƒ>AGR¡¶®ž‰ve5"++!$" .12,!! "! ! JJLMLLKD5  +    +  +  +3P\m†•|E?Ww¤®Ÿz¦ƒ*11''1/ =AB)  KKNMKKID;%->5-:3:@C.5AC52=  (+ 3 !?Wf{Ž~o{˜©¨™‹²~(00&%-. #$EDN+   8WX=GCMZTZfdIL]IJLJKKKJA+1D3,@8FKL.9GG64F    kj(#$4S`u‚“¿Â£šž”ˆ|œÄx3qq;S¤Š69G6*MQQ( + +NeeRMDRd^]feGG[JJKLONMKE2>S@9LAVXY9H[]CG_) + + + \[%"$˜>cÊÃUYbksw‚ŒŠwx_’Þp:{s3O–v-I¿Óvj¥°¾¼Î€z7GuhLc[–˜{ts£Ÿ”¡¤ŽŠ’žJLNNOOUfkW`zL\ia|ƒoHv~Soo  #& 5bR$AHM˜¡pMNUXSSZhqlkx^›ër0QK-.<:#2NUQmª´µÏÖÀeO:FMGCHR¥”ssq†¥ŽŸž’Œ–¡PORRRSdnmYb|Naj_}†rJx„Tsj   +$%  ˆyFLIQY]dhbgnvlÚú±=77*,43$8UZ\lŽ”½¼Ï¸IY\DNHBF\”¥oop’³š‘ š–“— MOOOORdnmV`|Sgk^~‡uKw‚Tuh  #%+€¸¦UKKHEJS^dda[Ëûûýñ°^/1:8':VX`|˜¤ÆÃÖªKPICMD?Abš¨Žnrq«—•ª¡“–˜¢NNMQSUgpoU^SgiZ‰{Mx‚„Sye + + +  +%%!¤çٺɒBJNMKQ[\WL·ûûûýýýýû«G9$ ! >W[bx˜¡ËÅÛ³Z5G_LZN@q¢«Šnvs˜°”™¬ž˜œ¥¤MNOQQTgpnP^Zni\~†}QuU|c  + + +$& _×ÒáäÆÂÛyFKLKLNKO­ùúûûýýýýûûù¹K'%%EX[kœª×èîˆAzqv×ôúúüüùùýýýýüüüÊ…^^vœ¢jT[[;;*UzKYn^›´ª}x{©§’¥©£ž£¦ŸLMNOQViqkDN„bqt_…‹^z‰ƒ_‹_  %&AÒïúúúúõèóõóà¢f]kAjŸ†n¯êúúúüüûûýýýýüüüüùø§‚Ç¡nOOP7.Do[6^t³ºr½«š¯°ª¦§£“PMMPRVjokIBilŽn~Ž•]xŠad  +%'!?Ñøø÷ô÷÷öööôñôôôõ渲Ÿ‹‘ÝüííÛîûûûýýýýüüüüúùùúýýýýüÄÇØá¨7<3La^CV”·¼—l€šÇ¨¥´´±««µ”MNOQRYlpmK>€rc‘lx–^vŽ[ˆo   +')`êøøø÷õö÷öööóïóôôõõëÔÖÝäðë÷üúúûûûýýýýüüüüúøøúýýýýüßÉÒì¨QEMTQFHB¿Á“s‚~¢Ñ³¨¹´²®­µ‰NMPOOYmpkN8|~`‘kv–at•^„z' +  '&:Éøøøø÷òó÷öööõñóôôõõîåõõøúüüüüûûûûýýýýüüüüúúúúýýýýüùñùûYƒ[[UTG@‡ÅÊŽw…zªÏ´®¼¶³ª¯µƒLMNPPYnrlO6zŠ]‡tp›Ÿcn’—`z€-  +   ))–ìïõøø÷ôõ÷öööõñóôôõõñæóùùúüüüüûûûûýýýýüüüüù÷÷úýýýüûü˵٠­a€²˜²ˆ—ÀÇzƒ|­Ç±´Â¼µ±³²uNPQPQ]qtlN+o‘`{}t›žmg•šmw‹7 & +! !/MÈàáè÷÷ø÷÷øùùùøòôööõõóìðöööûûûûûûûûûûûûùùùùù÷÷ùúùúøùû¸OHnµlZFZ}Q¤Â¾„€†·Æª³Ã¿·´¸ªmNNMNQ]qtlP$a^]Žrvb•™xv9   !!xúæÙâ÷÷øõöøùùùøõõööõõôóôöööûûûûûûûûûûûûùùùùùøøùõóúø÷úàkD\‹P|Ã]’­p¸À¸~„‰‰»Ã¡µÇÁµ±²›lLNPRR_wytgYbs]XpYk~UF{ees, $!!6æèÕØ÷÷ø÷÷øùùùùóôööõõõóõöööûûûûûûûûûûûûùùùùùøùùôõúúùøùû¶™–RazrVi‡ÇƬxˆ‡’ÅÀ¸³­‘nKLMPS`rssvy|ƒ†‹‘“•™šœŸ£¥§©©«¬­««ª¨§¦¥¤£ ›°¼ÖðÛÏó÷øõõøùùùùôôööõõõôôôõöûûúúûûûûûûûûùùùùùøøùúúúúõëøð†LZ?HKDG:r¾±kny•Ƴ§Â½¶´¥‹wKLNPRZH9:99<=<>=@=::<;;==?@BGLORUY_ciosx~ƒ„€±ÄÏãоï÷øôóøöööõóöööõõõñóéó÷øøø÷ûûûûûûûûøøøøûûûû÷÷ùùôÓùùÜÑÑÒÔÔÕÖÖÕÔÔ×ÙÞÜÛÙ×ÖÖÙØ×ÙÚÜÙLKMOP^lnlllmnopsuuuwwvutsqpopnmmjhgeeb`__]\_»ÀÐÇÛÂç÷øõõøöööõðòööõõôïëÞô÷øøø÷ûûûûûûûûøøøøûùúûîñøù÷Ùúü¶x{}}~€ƒ…‡ŠŠ‹Œ“”••–—˜–JLMKN\nrsru{}€…‡‹ŒŽ’“•”•—˜—˜™›Ÿž  Ÿ¡££££¢£¯ßÆÚÂÚÐß÷øôôøõõöôîóööõõõðìä÷÷øøøøûûûûûûûûøøøøûûûûðòùùøâüüÕ…{zvvtrrqpprqpoommmmkkihgheLKJNOK: + +  $',048:>CHNTX^chd—æÉÍÇÂÇáöøôôøöööôíñööõõõîëñ÷÷ø÷õöûûûûûûûûøøøøûûûûÑßøõêàüüùØÉÇÅÅÄÄÄÄÅÃÄÄÄÄÂÁÁ¿¿¿½»º¸·´LMLLMNH*  }èÖËÚՏɸùõôùõõõóíñ÷÷öööðêöùùööòôûûûûúúúúùùùùûûûûÅÖöñÝäùùý¶o{…ˆ•™ ¢¥©®´¸·¸¹¼ÀÃÆÂLJJLJJG4 + †ëæÇâá½É÷ùõñøõõõôïð÷÷öööïé÷ùùööíðûûûûúúúúùùùùûûûûáêëáÍäùùýÐE(%!KKLLIIH>% ˆíïÓÚÙ¼Îõù÷ñ÷õõõõðñ÷÷öööïç÷ùùööóôûûûûúùùúùùùùûûûúãâåâÞôùùýõ{&#!! !!!!" !#LLKLKIE?-  êóàÒÏ­Éóùøõøõõõôðð÷÷öööðçõùùööòóûûûûúøøúùùùùûö÷÷æÙÍÚÜôùùýý¯2&$#""!!! !!""!!"!#""$MKLMJFGB5   4¬ðöèÓÖ¥»ðøöôøõõõõñï÷÷÷÷÷ðâòøøööòôûûûûûùôúûûûûüüüæÏÊËÞàôüüûûì`+$#$$!$$""#! ######%'&KIJJIGEB:( N¾ñöìØÎ¶¿ëø÷òõõõõõïêö÷÷÷õëæ÷ø÷öôñôûûûûûöðùúûûûùíöâÉ»Îåéïûüûûû#)'%$"###""#####!#%%&%&)KHHJIIFC?/ lÒò÷ñßɪ­áööô÷õõõòãÈì÷÷õðéê÷øøöôòöûûûûûìåúûûûûùêùá°¡ÚíöðûüûûûÃ<+($$$'&&$#$$%$#$%&&&),+KIHJJHGD?4# …Þô÷ôäÁ¦ ÒñõòöõóïëÛÃâóòíááóøøøöòîöûú÷øõäòûûûûûîáùâ«—Îìøìöüûûûós(*(&'&&&&&&&&&'('&)*,..IHHIJFECA9(-¢æö÷õฤžÅéòðõôïëèÚÄÙñòçßç÷øøøõðíóýýýýùôúûùùù÷ßÓëÚ¬§Éïûåèüúúúú¨7-,)(''&'''')(&'*-./123IIIHEFECA<0 =¹ìõ÷÷뾬¢¸×èæñóïëçÖ½Óëèßãòøøøøõíêôýýýüïãöûùùù÷ØØóЫºÈóüïðûúúúúã\0-*)(''''('')*+,--0123HHGHHIGEC>4%UÙùöö÷îó¥ºÖÜàôõòìçÜÉÏåÞ×çòøøøøõìèõýýýýéÜöûùùùõâèôÁ¦ÀÓúüòçùúúúúû(,*+)))*+***+,-/223365GEHIFFDDB?7)kàúóñõí¶¡®ËÓÆæôòåÒÑÇÌáâäñòö÷øøôçäõýýýýöñúûùùøðÚïì°¯ÏëüüúïõúúúúûÈD0,**((*+++++./0344223GGHGGFIFCA<6-!FÁúúööóÚËØ©£»ÌÐÉÐÇÃÇÔÌÀÓçòñí÷ùúúöãßöüüüûïõûûúúöÜçú‘¬Ùöýûû÷éóûûûüüîk0/-/.,-./01212342243DDDEGGECB@<7."`¯÷úöööóáÞĪ»ÆÉ¼ÊÎÈÍÚλÓëõïí÷÷ø÷óÕßöüüüùèóûúùøîÛêò¹‹¦Ìðüûûûìîûûúûüü 1.-.--.-0/0223310110CBDDECDB??<80$,{w³Ù¼µ¿® ¯°§ºÅʶ¶¿Ç¼²º±ÆçóëèñóùùôÕÍôüüü÷âòûûòóòèõ÷¶‚”­àûúúúïÙòûûüüüÜZ111/./0110111310110BABDEEFC@?=;4)  7§Ïðúûí²‘–ެºÆº°¥”Š™§³ÉìôæÚêöôõõâÑòüüüøãíõôðõõñ÷÷ªy˜¤ÐííçÜÛìûûûüüüú’0200010011331110121D?ACEDEECA>;7,#lͺÎ÷ûûûûô®qy¢ ‘‰“§›qw’¢¼ìóßÜíôùùóâÌíüüüüòöûöóúúãîð–n›´È½ÝøúúûûûûüüüüÌM5331121/1220100220?=@BDDDDB@=97.%!¢Ì¯ÐñûŒ™ˆjrut˜¯¥~UhŠ¢ÆìÕÕëõùøðÝÇæüüüùëîìêíìäÚðìˆj’¤Ôýúúúúûûûûü÷ÍŸ`9431121212111100/00@=AAEHGDC@>:62&R¯…A*\qsrmaYWUk•±¤T#’ÊÚòóñøõçÉß÷úúñéñíï÷öíÚòæ€j Àþøøøøû¿j;=UG7322243122112100110-.?=>@CDEDCA><83* ,0$,Rfgeb_URU]h¨™S + ŽÈ×ÜïõöóåËÚóùúöôûüøøüöîøæ|b‘«›Çð¹X5?BIL;2222201232332111221011/?<=>BDDA@BA>;4+!  !" !""!$$%$'&(6Q\\_b]ZXZXR^yœ Y (œ¬ÁíõùùõçÍÓîúúúüüüûúú÷ñøÜŠo‡ Œ|Z:;AJOE7355356866544565565553311>=??BBCDCA@>950! "!!#"!""$$%#$$%%&*29GQUWYUTTLDEVWZeX9180>Ž£°òøùùöìÒÕæöúúüüüüùöñìõךry•M==AJTS<6799788768987677886676765 \ No newline at end of file diff --git a/SD-VBS/common/toolbox/toolbox_basic/affine/readpgm.m b/SD-VBS/common/toolbox/toolbox_basic/affine/readpgm.m new file mode 100755 index 0000000..a5fd7f2 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/affine/readpgm.m @@ -0,0 +1,26 @@ +function img = pgmread(filename) +% function img = pgmread(filename) +% this is my version of pgmread for the pgm file created by XV. +% +% this program also corrects for the shifts in the image from pm file. + + +fid = fopen(filename,'r'); +fscanf(fid, 'P5\n'); +cmt = '#'; +while findstr(cmt, '#'), + cmt = fgets(fid); + if length(findstr(cmt, '#')) ~= 1, + YX = sscanf(cmt, '%d %d'); + y = YX(1); x = YX(2); + end +end + +fgets(fid); + +%img = fscanf(fid,'%d',size); +%img = img'; + +img = fread(fid,[y,x],'uint8'); +img = img'; +fclose(fid); diff --git a/SD-VBS/common/toolbox/toolbox_basic/affine/simulation.m b/SD-VBS/common/toolbox/toolbox_basic/affine/simulation.m new file mode 100755 index 0000000..2186a6d --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/affine/simulation.m @@ -0,0 +1,42 @@ +clear + +figure(1);colormap(gray); + +%------------ Parameters -------------------------- +window_size_h = 40; +window_size = 2*window_size_h+1; +noise_level = 40/256; + +% define A and D +x_ext = -0.423; +ext = 1.232; +A = [ext+x_ext, 0.2534; 0.3423,ext]; + +D = [3,1]; + +%------------- compute image I and J --------------- +disp('generating I') +I_init = gen_feature_s(window_size); +[size_y,size_x] = size(I_init); + +%define image center +[center_x,center_y] = find_center(size_x,size_y); + +% adding noise to image I +I = I_init+noise_level*rand(size_y,size_x); +% make sure all intensities are positive +I = I.*(I>0); + +disp('computing J') +J_init = compute_J(A,D,I_init,[center_x,center_y],[window_size_h,window_size_h]); +J = J_init+noise_level*rand(size_y,size_x); +J = J.*(J>0); + + +%------------- compute A and residue ---------------- +c = [center_x,center_y]; +num_iter = 8; w = 9;win_h = [window_size_h,window_size_h]; + +fig_disp = 1; +[Ac,Dc,mask] = compute_AD_disp(I,J,c,c,win_h,num_iter,w,fig_disp); + diff --git a/SD-VBS/common/toolbox/toolbox_basic/affine/sports1_11_28.jpeg b/SD-VBS/common/toolbox/toolbox_basic/affine/sports1_11_28.jpeg new file mode 100755 index 0000000..39ebed5 Binary files /dev/null and b/SD-VBS/common/toolbox/toolbox_basic/affine/sports1_11_28.jpeg differ diff --git a/SD-VBS/common/toolbox/toolbox_basic/affine/test_affine.m b/SD-VBS/common/toolbox/toolbox_basic/affine/test_affine.m new file mode 100755 index 0000000..41b48b9 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/affine/test_affine.m @@ -0,0 +1,33 @@ +%%% This is a test program for Affine tracker %%%% + +disp(sprintf('This is a test program of Affine tracker')); + +%% read in images + +disp(sprintf('read in images')); +I = readpgm('pan.0.pgm'); +J = readpgm('pan.1.pgm'); + +figure(1); im(I); colormap(gray); +figure(2); im(J); colormap(gray); + + +figure(1);disp(sprintf('click on the center of a image window')); +c = round(ginput(1)); + +%% compute the displacement of that image window +disp(sprintf('computing...')); + +win_hsize_temp = [8,8]; +w = 3; +num_iter = 6; + +disp_flag = 1; + +win_h = win_hsize_temp + [w,w]; +if disp_flag == 1, + figure_id = 3; + [A,D,mask] = compute_AD_disp(I,J,c,c,win_h,num_iter,w,figure_id); +else + [A,D,mask] = compute_AD(I,J,c,c,win_h,num_iter,w); +end diff --git a/SD-VBS/common/toolbox/toolbox_basic/affinityic.c b/SD-VBS/common/toolbox/toolbox_basic/affinityic.c new file mode 100755 index 0000000..e48762a --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/affinityic.c @@ -0,0 +1,186 @@ +/*================================================================ +* function w = affinityic(emag,ephase,pi,pj,sigma) +* Input: +* emag = edge strength at each pixel +* ephase = edge phase at each pixel +* [pi,pj] = index pair representation for MALTAB sparse matrices +* sigma = sigma for IC energy +* Output: +* w = affinity with IC at [pi,pj] +* + +% test sequence +f = synimg(10); +[i,j] = cimgnbmap(size(f),2); +[ex,ey,egx,egy] = quadedgep(f); +a = affinityic(ex,ey,egx,egy,i,j) +show_dist_w(f,a); + +* Jianbo Shi, Stella X. Yu, Nov 19, 2001. +*=================================================================*/ + +# include "mex.h" +# include "math.h" + +void mexFunction( + int nargout, + mxArray *out[], + int nargin, + const mxArray *in[] +) +{ + /* declare variables */ + int nr, nc, np, total; + int i, j, k, ix, iy, jx, jy, ii, jj, iip1, jjp1, iip2, jjp2, step; + double sigma, di, dj, a, z, maxori, phase1, phase2, slope; + int *ir, *jc; + unsigned long *pi, *pj; + double *emag, *ephase, *w; + + /* check argument */ + if (nargin<4) { + mexErrMsgTxt("Four input arguments required"); + } + if (nargout>1) { + mexErrMsgTxt("Too many output arguments"); + } + + /* get edgel information */ + nr = mxGetM(in[0]); + nc = mxGetN(in[0]); + if ( nr*nc ==0 || nr != mxGetM(in[1]) || nc != mxGetN(in[1]) ) { + mexErrMsgTxt("Edge magnitude and phase shall be of the same image size"); + } + emag = mxGetPr(in[0]); + ephase = mxGetPr(in[1]); + np = nr * nc; + + /* get new index pair */ + if (!mxIsUint32(in[2]) | !mxIsUint32(in[3])) { + mexErrMsgTxt("Index pair shall be of type UINT32"); + } + if (mxGetM(in[3]) * mxGetN(in[3]) != np + 1) { + mexErrMsgTxt("Wrong index representation"); + } + pi = mxGetData(in[2]); + pj = mxGetData(in[3]); + + /* create output */ + out[0] = mxCreateSparse(np,np,pj[np],mxREAL); + if (out[0]==NULL) { + mexErrMsgTxt("Not enough memory for the output matrix"); + } + w = mxGetPr(out[0]); + ir = mxGetIr(out[0]); + jc = mxGetJc(out[0]); + + /* find my sigma */ + if (nargin<5) { + sigma = 0; + for (k=0; ksigma) { sigma = emag[k]; } + } + sigma = sigma / 10; + printf("sigma = %6.5f",sigma); + } else { + sigma = mxGetScalar(in[4]); + } + a = 1.0/ (sigma); + + /* computation */ + total = 0; + for (j=0; j= abs(dj)) { + slope = dj / di; + step = (iy>=jy) ? 1 : -1; + + iip1 = jy; + jjp1 = jx; + + + for (ii=0;ii maxori){ + maxori = z; + } + } + + iip1 = iip2; + jjp1 = jjp2; + phase1 = phase2; + } + + /* sample in j direction */ + } else { + slope = di / dj; + step = (ix>=jx) ? 1: -1; + + jjp1 = jx; + iip1 = jy; + + + for (jj=0;jj maxori){ + maxori = z; + } + + } + + iip1 = iip2; + jjp1 = jjp2; + phase1 = phase2; + } + } + + maxori = 0.5 * maxori*a; + maxori = exp(-maxori*maxori); + } + ir[total] = i; + + w[total] = maxori + 0.005; + total = total + 1; + + } /* i */ + } /* j */ + + jc[np] = total; +} diff --git a/SD-VBS/common/toolbox/toolbox_basic/calib/TOOLBOX_calib.tar b/SD-VBS/common/toolbox/toolbox_basic/calib/TOOLBOX_calib.tar new file mode 100755 index 0000000..92ab3a0 Binary files /dev/null and b/SD-VBS/common/toolbox/toolbox_basic/calib/TOOLBOX_calib.tar differ diff --git a/SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/Distor2Calib.m b/SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/Distor2Calib.m new file mode 100755 index 0000000..a82f583 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/Distor2Calib.m @@ -0,0 +1,391 @@ +function [fc_2,Rc_2,Tc_2,H_2,distance,V_vert,V_hori,x_all_c,V_hori_pix,V_vert_pix,V_diag1_pix,V_diag2_pix]=Distor2Calib(k_dist,grid_pts_centered,n_sq_x,n_sq_y,Np,W,L,Xgrid_2,f_ini,N_iter,two_focal); + +% Computes the calibration parameters knowing the +% distortion factor k_dist + +% grid_pts_centered are the grid point coordinates after substraction of +% the optical center. + +% can give an optional guess for the focal length f_ini (can set to []) +% can provide the number of iterations for the Iterative Vanishing Point Algorithm + +% if the focal length is known perfectly, then, there is no need to iterate, +% and therefore, one can fix: N_iter = 0; + +% California Institute of Technology +% (c) Jean-Yves Bouguet - October 7th, 1997 + + + +%keyboard; + +if exist('two_focal'), + if isempty(two_focal), + two_focal=0; + end; +else + two_focal = 0; +end; + + +if exist('N_iter'), + if ~isempty(N_iter), + disp('Use number of iterations provided'); + else + N_iter = 10; + end; +else + N_iter = 10; +end; + +if exist('f_ini'), + if ~isempty(f_ini), + disp('Use focal provided'); + if length(f_ini)<2, f_ini=[f_ini;f_ini]; end; + fc_2 = f_ini; + x_all_c = [grid_pts_centered(1,:)/fc_2(1);grid_pts_centered(2,:)/fc_2(2)]; + x_all_c = comp_distortion(x_all_c,k_dist); % we can this time!!! + else + fc_2 = [1;1]; + x_all_c = grid_pts_centered; + end; +else + fc_2 = [1;1]; + x_all_c = grid_pts_centered; +end; + + +dX = W/n_sq_x; +dY = L/n_sq_y; + + +N_x = n_sq_x+1; +N_y = n_sq_y+1; + + +x_grid = zeros(N_x,N_y); +y_grid = zeros(N_x,N_y); + + + + + +%%% Computation of the four vanishing points in pixels + + + x_grid(:) = grid_pts_centered(1,:); + y_grid(:) = grid_pts_centered(2,:); + + for k=1:n_sq_x+1, + [U,S,V] = svd([x_grid(k,:);y_grid(k,:);ones(1,n_sq_y+1)]); + vert(:,k) = U(:,3); + end; + + for k=1:n_sq_y+1, + [U,S,V] = svd([x_grid(:,k)';y_grid(:,k)';ones(1,n_sq_x+1)]); + hori(:,k) = U(:,3); + end; + + % 2 principle Vanishing points: + [U,S,V] = svd(vert); + V_vert = U(:,3); + [U,S,V] = svd(hori); + V_hori = U(:,3); + + + + % Square warping: + + + vert_first = vert(:,1) - dot(V_vert,vert(:,1))/dot(V_vert,V_vert) * V_vert; + vert_last = vert(:,n_sq_x+1) - dot(V_vert,vert(:,n_sq_x+1))/dot(V_vert,V_vert) * V_vert; + + hori_first = hori(:,1) - dot(V_hori,hori(:,1))/dot(V_hori,V_hori) * V_hori; + hori_last = hori(:,n_sq_y+1) - dot(V_hori,hori(:,n_sq_y+1))/dot(V_hori,V_hori) * V_hori; + + + x1 = cross(hori_first,vert_first); + x2 = cross(hori_first,vert_last); + x3 = cross(hori_last,vert_last); + x4 = cross(hori_last,vert_first); + + x1 = x1/x1(3); + x2 = x2/x2(3); + x3 = x3/x3(3); + x4 = x4/x4(3); + + + + [square] = Rectangle2Square([x1 x2 x3 x4],W,L); + + y1 = square(:,1); + y2 = square(:,2); + y3 = square(:,3); + y4 = square(:,4); + + H2 = cross(V_vert,V_hori); + + V_diag1 = cross(cross(y1,y3),H2); + V_diag2 = cross(cross(y2,y4),H2); + + V_diag1 = V_diag1 / norm(V_diag1); + V_diag2 = V_diag2 / norm(V_diag2); + + V_hori_pix = V_hori; + V_vert_pix = V_vert; + V_diag1_pix = V_diag1; + V_diag2_pix = V_diag2; + + +% end of computation of the vanishing points in pixels. + + + + + + + + +if two_focal, % only if we attempt to estimate two focals... + % Use diagonal lines also to add two extra vanishing points (?) + N_min = min(N_x,N_y); + + if N_min < 2, + use_diag = 0; + two_focal = 0; + disp('Cannot estimate two focals (no existing diagonals)'); + else + use_diag = 1; + Delta_N = abs(N_x-N_y); + N_extra = round((N_min - Delta_N - 1)/2); + diag_list = -N_extra:Delta_N+N_extra; + N_diag = length(diag_list); + diag_1 = zeros(3,N_diag); + diag_2 = zeros(3,N_diag); + end; +else + % Give up the use of the diagonals (so far) + % it seems that the error is increased + use_diag = 0; +end; + + + +% The vertical lines: vert, Horizontal lines: hori +vert = zeros(3,n_sq_x+1); +hori = zeros(3,n_sq_y+1); + +for counter_k = 1:N_iter, % the Iterative Vanishing Points Algorithm to + % estimate the focal length accurately + + x_grid(:) = x_all_c(1,:); + y_grid(:) = x_all_c(2,:); + + for k=1:n_sq_x+1, + [U,S,V] = svd([x_grid(k,:);y_grid(k,:);ones(1,n_sq_y+1)]); + vert(:,k) = U(:,3); + end; + + for k=1:n_sq_y+1, + [U,S,V] = svd([x_grid(:,k)';y_grid(:,k)';ones(1,n_sq_x+1)]); + hori(:,k) = U(:,3); + end; + + % 2 principle Vanishing points: + [U,S,V] = svd(vert); + V_vert = U(:,3); + [U,S,V] = svd(hori); + V_hori = U(:,3); + + + + % Square warping: + + + vert_first = vert(:,1) - dot(V_vert,vert(:,1))/dot(V_vert,V_vert) * V_vert; + vert_last = vert(:,n_sq_x+1) - dot(V_vert,vert(:,n_sq_x+1))/dot(V_vert,V_vert) * V_vert; + + hori_first = hori(:,1) - dot(V_hori,hori(:,1))/dot(V_hori,V_hori) * V_hori; + hori_last = hori(:,n_sq_y+1) - dot(V_hori,hori(:,n_sq_y+1))/dot(V_hori,V_hori) * V_hori; + + + x1 = cross(hori_first,vert_first); + x2 = cross(hori_first,vert_last); + x3 = cross(hori_last,vert_last); + x4 = cross(hori_last,vert_first); + + x1 = x1/x1(3); + x2 = x2/x2(3); + x3 = x3/x3(3); + x4 = x4/x4(3); + + + + [square] = Rectangle2Square([x1 x2 x3 x4],W,L); + + y1 = square(:,1); + y2 = square(:,2); + y3 = square(:,3); + y4 = square(:,4); + + H2 = cross(V_vert,V_hori); + + V_diag1 = cross(cross(y1,y3),H2); + V_diag2 = cross(cross(y2,y4),H2); + + V_diag1 = V_diag1 / norm(V_diag1); + V_diag2 = V_diag2 / norm(V_diag2); + + + + + % Estimation of the focal length, and normalization: + + % Compute the ellipsis of (1/f^2) positions: + % a * (1/fx)^2 + b * (1/fx)^2 = -c + + + a1 = V_hori(1); + b1 = V_hori(2); + c1 = V_hori(3); + + a2 = V_vert(1); + b2 = V_vert(2); + c2 = V_vert(3); + + a3 = V_diag1(1); + b3 = V_diag1(2); + c3 = V_diag1(3); + + a4 = V_diag2(1); + b4 = V_diag2(2); + c4 = V_diag2(3); + + + if two_focal, + + + A = [a1*a2 b1*b2;a3*a4 b3*b4]; + b = -[c1*c2;c3*c4]; + + f = sqrt(abs(1./(inv(A)*b))); + + else + + f = sqrt(abs(-(c1*c2*(a1*a2 + b1*b2) + c3*c4*(a3*a4 + b3*b4))/(c1^2*c2^2 + c3^2*c4^2))); + + f = [f;f]; + + end; + + + + % REMARK: + % if both a and b are small, the calibration is impossible. + % if one of them is small, only the other focal length is observable + % if none is small, both focals are observable + + + fc_2 = fc_2 .* f; + + + % DEBUG PART: fix focal to 500... + %fc_2= [500;500]; disp('Line 293 to be earased in Distor2Calib.m'); + + + % end of focal compensation + + % normalize by the current focal: + + x_all = [grid_pts_centered(1,:)/fc_2(1);grid_pts_centered(2,:)/fc_2(2)]; + + % Compensate by the distortion factor: + + x_all_c = comp_distortion(x_all,k_dist); + +end; + +% At that point, we hope that the distortion is gone... + +x_grid(:) = x_all_c(1,:); +y_grid(:) = x_all_c(2,:); + +for k=1:n_sq_x+1, + [U,S,V] = svd([x_grid(k,:);y_grid(k,:);ones(1,n_sq_y+1)]); + vert(:,k) = U(:,3); +end; + +for k=1:n_sq_y+1, + [U,S,V] = svd([x_grid(:,k)';y_grid(:,k)';ones(1,n_sq_x+1)]); + hori(:,k) = U(:,3); +end; + +% Vanishing points: +[U,S,V] = svd(vert); +V_vert = U(:,3); +[U,S,V] = svd(hori); +V_hori = U(:,3); + +% Horizon: + +H_2 = cross(V_vert,V_hori); + +% H_2 = cross(V_vert,V_hori); + +% pick a plane in front of the camera (positive depth) +if H_2(3) < 0, H_2 = -H_2; end; + + +% Rotation matrix: + +if V_hori(1) < 0, V_hori = -V_hori; end; + +V_hori = V_hori/norm(V_hori); +H_2 = H_2/norm(H_2); + +V_hori = V_hori - dot(V_hori,H_2)*H_2; + +Rc_2 = [V_hori cross(H_2,V_hori) H_2]; + +Rc_2 = Rc_2 / det(Rc_2); + +%omc_2 = rodrigues(Rc_2); + +%Rc_2 = rodrigues(omc_2); + +% Find the distance of the plane for translation vector: + +xc_2 = [x_all_c;ones(1,Np)]; + +Zc_2 = 1./sum(xc_2 .* (Rc_2(:,3)*ones(1,Np))); + +Xo_2 = [sum(xc_2 .* (Rc_2(:,1)*ones(1,Np))).*Zc_2 ; sum(xc_2 .* (Rc_2(:,2)*ones(1,Np))).*Zc_2]; + +XXo_2 = Xo_2 - mean(Xo_2')'*ones(1,Np); + +distance_x = norm(Xgrid_2(1,:))/norm(XXo_2(1,:)); +distance_y = norm(Xgrid_2(2,:))/norm(XXo_2(2,:)); + + +distance = sum(sum(XXo_2(1:2,:).*Xgrid_2(1:2,:)))/sum(sum(XXo_2(1:2,:).^2)); + +alpha = abs(distance_x - distance_y)/distance; + +if (alpha>0.1)&~two_focal, + disp('Should use two focals in x and y...'); +end; + +% Deduce the translation vector: + +Tc_2 = distance * H_2; + + + + + +return; + + V_hori_pix/V_hori_pix(3) + V_vert_pix/V_vert_pix(3) + V_diag1_pix/V_diag1_pix(3) + V_diag2_pix/V_diag2_pix(3) diff --git a/SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/Multi_Calib_oulu.m b/SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/Multi_Calib_oulu.m new file mode 100755 index 0000000..62ca9ae --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/Multi_Calib_oulu.m @@ -0,0 +1,12 @@ + +% enter image names, numbers, ... +data_calib; + +%read images from files +ima_read_calib; + +click_calib; + +%go_calib; % the original version + +go_calib_optim; diff --git a/SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/Rectangle2Square.m b/SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/Rectangle2Square.m new file mode 100755 index 0000000..a6bbbe5 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/Rectangle2Square.m @@ -0,0 +1,19 @@ +function [square] = Rectangle2Square(rectangle,L,W); + +% Generate the square from a rectangle of known segment lengths +% from pt1 to pt2 : L +% from pt2 to pt3 : W + +[u_hori,u_vert] = UnWarpPlane(rectangle); + +coeff_x = sqrt(W/L); +coeff_y = 1/coeff_x; + +x_coord = [ 0 coeff_x coeff_x 0]; +y_coord = [ 0 0 coeff_y coeff_y]; + + +square = rectangle(:,1) * ones(1,4) + u_hori*x_coord + u_vert*y_coord; +square = square ./ (ones(3,1)*square(3,:)); + + diff --git a/SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/UnWarpPlane.m b/SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/UnWarpPlane.m new file mode 100755 index 0000000..8addf52 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/UnWarpPlane.m @@ -0,0 +1,54 @@ +function [u_hori,u_vert] = UnWarpPlane(x1,x2,x3,x4); + +% Recovers the two 3D directions of the rectangular patch x1x2x3x4 +% x1 is the origin point, ie any point of planar coordinate (x,y) on the +% rectangular patch will be projected on the image plane at: +% x1 + x * u_hori + y * u_vert +% +% Note: u_hori and u_vert are also the two vanishing points. + + +if nargin < 4, + + x4 = x1(:,4); + x3 = x1(:,3); + x2 = x1(:,2); + x1 = x1(:,1); + +end; + + +% Image Projection: +L1 = cross(x1,x2); +L2 = cross(x4,x3); +L3 = cross(x2,x3); +L4 = cross(x1,x4); + +% Vanishing point: +V1 = cross(L1,L2); +V2 = cross(L3,L4); + +% Horizon line: +H = cross(V1,V2); + +if H(3) < 0, H = -H; end; + + +H = H / norm(H); + + +X1 = x1 / dot(H,x1); +X2 = x2 / dot(H,x2); +X3 = x3 / dot(H,x3); +X4 = x4 / dot(H,x4); + +scale = X1(3); + +X1 = X1/scale; +X2 = X2/scale; +X3 = X3/scale; +X4 = X4/scale; + + +u_hori = X2 - X1; +u_vert = X4 - X1; diff --git a/SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/add_suppress.m b/SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/add_suppress.m new file mode 100755 index 0000000..b9bcc57 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/add_suppress.m @@ -0,0 +1,91 @@ + check_active_images; + + +fprintf(1,'\nThis function is useful to select a subset of images to calibrate\n'); + + fprintf(1,'\nThere are currently %d active images selected for calibration (out of %d):\n',length(ind_active),n_ima); + + if ~isempty(ind_active), + + for ii = 1:length(ind_active)-2, + + fprintf(1,'%d, ',ind_active(ii)); + + end; + + fprintf(1,'%d and %d.',ind_active(end-1),ind_active(end)); + + end; + + fprintf(1,'\n'); + + +fprintf(1,'\nDo you want to suppress or add images from that list?\n'); + +choice = 2; + +while (choice~=0)&(choice~=1), + choice = input('For suppressing images enter 0, for adding images enter 1 ([]=no change): '); + if isempty(choice), + fprintf(1,'No change applied to the list of active images.\n'); + return; + end; + if (choice~=0)&(choice~=1), + disp('Bad entry. Try again.'); + end; +end; + + +if choice, + + ima_numbers = input('Number(s) of image(s) to add ([] = all images) = '); + +if isempty(ima_numbers), + fprintf(1,'All %d images are now active\n',n_ima); + ima_proc = 1:n_ima; + else + ima_proc = ima_numbers; + end; + +else + + + ima_numbers = input('Number(s) of image(s) to suppress ([] = no image) = '); + + if isempty(ima_numbers), + fprintf(1,'No image has been suppressed. No modication of the list of active images.\n',n_ima); + ima_proc = []; + else + ima_proc = ima_numbers; + end; + +end; + +if ~isempty(ima_proc), + + active_images(ima_proc) = choice * ones(1,length(ima_proc)); + +end; + + + check_active_images; + + + fprintf(1,'\nThere is now a total of %d active images for calibration:\n',length(ind_active)); + + if ~isempty(ind_active), + + for ii = 1:length(ind_active)-2, + + fprintf(1,'%d, ',ind_active(ii)); + + end; + + fprintf(1,'%d and %d.',ind_active(end-1),ind_active(end)); + + end; + + fprintf(1,'\n\nYou may now run ''Calibration'' to recalibrate based on this new set of images.\n'); + + + \ No newline at end of file diff --git a/SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/analyse_error.m b/SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/analyse_error.m new file mode 100755 index 0000000..5bfa3b5 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/analyse_error.m @@ -0,0 +1,104 @@ +% Color code for each image: + +check_active_images; + +if ~exist(['ex_' num2str(ind_active(1)) ]), + fprintf(1,'Need to calibrate before analysing reprojection error. Maybe need to load Calib_Results.mat file.\n'); + return; +end; + + +if ~exist('no_grid'), + no_grid = 0; +end; + +colors = 'brgkcm'; + + +figure(5); + +for kk = 1:n_ima, + if active_images(kk) & eval(['~isnan(y_' num2str(kk) '(1,1))']), + eval(['plot(ex_' num2str(kk) '(1,:),ex_' num2str(kk) '(2,:),''' colors(rem(kk-1,6)+1) '+'');']); + hold on; + end; +end; +hold off; +axis('equal'); +if 1, %~no_grid, + title('Reprojection error (in pixel) - To exit: right button'); +else + title('Reprojection error (in pixel)'); +end; +xlabel('x'); +ylabel('y'); + +set(5,'Name','error','NumberTitle','off'); + + + +%err_std = std(ex')'; + +%fprintf(1,'Pixel error: err = [ %3.5f %3.5f]\n\n',err_std); + +b = 1; + +while b==1, + +[xp,yp,b] = ginput3(1); + +if b==1, +ddd = (ex(1,:)-xp).^2 + (ex(2,:)-yp).^2; + +[mind,indmin] = min(ddd); + + +done = 0; +kk_ima = 1; +while (~done)&(kk_ima<=n_ima), + %fprintf(1,'%d...',kk_ima); + eval(['ex_kk = ex_' num2str(kk_ima) ';']); + sol_kk = find((ex_kk(1,:) == ex(1,indmin))&(ex_kk(2,:) == ex(2,indmin))); + if isempty(sol_kk), + kk_ima = kk_ima + 1; + else + done = 1; + end; +end; + +if ~no_grid, + +eval(['n_sq_x = n_sq_x_' num2str(kk_ima) ';']); +eval(['n_sq_y = n_sq_y_' num2str(kk_ima) ';']); + +Nx = n_sq_x+1; +Ny = n_sq_y+1; + +y1 = floor((sol_kk-1)./Nx); +x1 = sol_kk - 1 - Nx*y1; %rem(sol_kk-1,Nx); + +y1 = (n_sq_y+1) - y1; +x1 = x1 + 1; + +fprintf(1,'\nSelected image: %d\nSelected point: (col,row)=(%d,%d)\nNcol=%d, Nrow=%d\n',[kk_ima x1 y1 Nx Ny]); +fprintf(1,'Pixel error = (%3.5f,%3.5f)\n',[ex(1,indmin) ex(2,indmin)]); + +else + + eval(['x_kk = x_' num2str(kk_ima) ';']); + + xpt = x_kk(:,sol_kk); + +fprintf(1,'\nSelected image: %d\nImage coordinates (in pixel): (%3.2f,%3.2f)\n',[kk_ima xpt']); +fprintf(1,'Pixel error = (%3.5f,%3.5f)\n',[ex(1,indmin) ex(2,indmin)]); + + +end; + + +end; + +end; + +disp('done'); + diff --git a/SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/calib.m b/SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/calib.m new file mode 100755 index 0000000..5b0fdac --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/calib.m @@ -0,0 +1,74 @@ +if ~exist('instructions'), instructions = 1; end; + +if instructions, + +fprintf(1,'\n'); +fprintf(1,'*----------------------------------------------------------------------------------------------------*\n'); +fprintf(1,'| Main Calibration toolbox (2D and 3D rigs) |\n'); +fprintf(1,'| (c) Jean-Yves Bouguet - September 9th, 1999 |\n'); +fprintf(1,'*----------------------------------------------------------------------------------------------------*\n\n\n'); + +fprintf(1,'CLICK ON:\n\n'); + +fprintf(1,'2D: To perform camera calibration from multiple views of a 2D planar grid. \n'); +fprintf(1,' Set default size of grid (in dX_default and dY_default) in click_calib.m.\n'); +fprintf(1,'3D: To perform camera calibration from multiple views of a 3D grid corner. \n'); +fprintf(1,' Set default size of grids (in dX_default and dY_default) in click_calib3D.m.\n'); +fprintf(1,'Exit: To close the calibration tool. \n'); + +end; + +instructions = 0; + +fig_number = 1; + +n_row = 1; +n_col = 3; + +string_list = cell(n_row,n_col); +callback_list = cell(n_row,n_col); + +x_size = 40; +y_size = 20; + +title_figure = 'Calibration tool'; + +string_list{1,1} = '2D rig'; +string_list{1,2} = '3D rig'; +string_list{1,3} = 'Exit'; + +callback_list{1,1} = 'calib_gui;'; +callback_list{1,2} = 'calib3D_gui;'; +callback_list{1,3} = ['disp(''Bye. To run again, type calib.''); close(' num2str(fig_number) ');']; + + +figure(fig_number); clf; +pos = get(fig_number,'Position'); + +fig_size_x = x_size*n_col+(n_col+1)*2; +fig_size_y = y_size*n_row+(n_row+1)*2; + +set(fig_number,'Units','points', ... + 'BackingStore','off', ... + 'Color',[0.8 0.8 0.8], ... + 'MenuBar','none', ... + 'Resize','off', ... + 'Name',title_figure, ... +'Position',[pos(1) pos(2) fig_size_x fig_size_y], ... +'NumberTitle','off'); + + +for i=n_row:-1:1, + for j = n_col:-1:1, + if (~isempty(callback_list{i,j}))&(~isempty(string_list{i,j})), + uicontrol('Parent',fig_number, ... + 'Units','points', ... + 'Callback',callback_list{i,j}, ... + 'ListboxTop',0, ... + 'Position',[(2+(j-1)*(x_size+2)) (fig_size_y - i*(2+y_size)) x_size y_size], ... + 'String',string_list{i,j}, ... + 'Tag','Pushbutton1'); + end; + end; +end; + diff --git a/SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/calib3D_gui.m b/SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/calib3D_gui.m new file mode 100755 index 0000000..ff24f6b --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/calib3D_gui.m @@ -0,0 +1,115 @@ +if ~exist('instructions3D'), instructions3D = 1; end; + +if instructions3D, + +fprintf(1,'\n'); +fprintf(1,'*----------------------------------------------------------------------------------------------------*\n'); +fprintf(1,'| Canera calibration from multiple images of the Intel 3D calibration rig |\n'); +fprintf(1,'| (c) Jean-Yves Bouguet - September 2nd, 1999 |\n'); +fprintf(1,'*----------------------------------------------------------------------------------------------------*\n\n\n'); + +fprintf(1,'LIST OF CALIBRATION COMMANDS (to be executed from 1 to 5):\n\n'); + +fprintf(1,'1- Image names: Lets the user enter the file names of the calibration images (max = 30 images).\n'); +fprintf(1,' It includes basename, image type (''tif'', ''bmp'' or ''ras''), numbering scheme.\n'); +fprintf(1,' Automatically launchs the next step (Read images).\n'); +fprintf(1,'2- Read images: Reads in the calibration images from files.\n'); +fprintf(1,' Does not automatically launch the next step (Extract grid corners).\n'); +fprintf(1,'3- Extract grid corners: Extracts the grid corners from the image.\n'); +fprintf(1,' Based six maual clicks per image.\n'); +fprintf(1,' The calibration data is saved under ''calib_data.mat''.\n'); +fprintf(1,' Automatically launchs the next step (Run calibration).\n'); +fprintf(1,'4- Run calibration: Main calibration procedure.\n'); +fprintf(1,' Optimization of intrinsic and extrinsic parameters to minimize\n'); +fprintf(1,' the reprojection error (in the least squares sense.\n'); +fprintf(1,' Estimated parameters: 2 focal lengths, principal point,\n'); +fprintf(1,' radial (2 coeff. -> 4 degree model) and tangential (2 coeff.) distortion,\n'); +fprintf(1,' and extrinsic parameters (6 parameters per image).\n'); +fprintf(1,' The final solution is saved under ''Calib_Results.mat''.\n'); +fprintf(1,' For a description of the intrinsic camera model, refer to the reference:\n'); +fprintf(1,' "A Four-step Camera Calibration Procedure with implicit Image Correction"\n'); +fprintf(1,' Janne Heikkila and Olli Silven, Infotech Oulu and Department of EE\n'); +fprintf(1,' University of Oulu, Appeared in CVPR''97, Puerto Rico.\n'); +fprintf(1,' Visit http://www.ee.oulu.fi/~jth/calibr/Calibration.html\n'); +fprintf(1,' Automatically launchs the next step (Graphic out).\n'); +fprintf(1,'5- Graphic out: Generates the graphical output associated to the current calibration solution.\n'); +fprintf(1,' It shows the 3D locations of the grids, and reprojects the 3D patterns on the\n'); +fprintf(1,' original calibration images.\n'); +fprintf(1,'6- sol. with center: Lets the user select the calibration solution with computed principal point.\n'); +fprintf(1,' This is the default case (solution retained after Run calibration).\n'); +fprintf(1,' Automatically (re)generates the graphical output associated to that solution.\n'); +fprintf(1,'7- sol. without center: Lets the users select the calibration solution without computed principal point.\n'); +fprintf(1,' In that case, the principal point is assumed at the center of the image.\n'); +fprintf(1,' Automatically generates the graphical output associated to that solution.\n'); +fprintf(1,' This option is sometimes useful when the principal point is difficult to\n'); +fprintf(1,' estimate (in particular when the camera field of view is small).\n'); +fprintf(1,'8- Back to main: Goes back to the main calbration toolbox window.\n\n\n'); + +end; + +instructions3D = 0; + +global X_1 x_1 X_2 x_2 X_3 x_3 X_4 x_4 X_5 x_5 X_6 x_6 X_7 x_7 X_8 x_8 X_9 x_9 X_10 x_10 X_11 x_11 X_12 x_12 X_13 x_13 X_14 x_14 X_15 x_15 X_16 x_16 X_17 x_17 X_18 x_18 X_19 x_19 X_20 x_20 X_21 x_21 X_22 x_22 X_23 x_23 X_24 x_24 X_25 x_25 X_26 x_26 X_27 x_27 X_28 x_28 X_29 x_29 X_30 x_30 + + +fig_number = 1; + +n_row = 2; +n_col = 4; + +string_list = cell(n_row,n_col); +callback_list = cell(n_row,n_col); + +x_size = 85; +y_size = 20; + +title_figure = 'Camera calibration tool (3D rig)'; + +string_list{1,1} = 'Image names'; +string_list{1,2} = 'Read images'; +string_list{1,3} = 'Extract grid corners'; +string_list{1,4} = 'Run calibration'; +string_list{2,1} = 'Graphic out'; +string_list{2,2} = 'sol. with center'; +string_list{2,3} = 'sol. without center'; +string_list{2,4} = 'Back to main'; + +callback_list{1,1} = 'data_calib;'; +callback_list{1,2} = 'ima_read_calib;'; +callback_list{1,3} = 'click_calib3D;'; +callback_list{1,4} = 'go_calib_optim3D;'; +callback_list{2,1} = 'graphout_calib3D;'; +callback_list{2,2} = 'select_sol_with_center3D;'; +callback_list{2,3} = 'select_sol_no_center3D;'; +callback_list{2,4} = 'calib;'; + + +figure(fig_number); clf; +pos = get(fig_number,'Position'); + +fig_size_x = x_size*n_col+(n_col+1)*2; +fig_size_y = y_size*n_row+(n_row+1)*2; + +set(fig_number,'Units','points', ... + 'BackingStore','off', ... + 'Color',[0.8 0.8 0.8], ... + 'MenuBar','none', ... + 'Resize','off', ... + 'Name',title_figure, ... +'Position',[pos(1) pos(2) fig_size_x fig_size_y], ... +'NumberTitle','off'); + + +for i=n_row:-1:1, + for j = n_col:-1:1, + if (~isempty(callback_list{i,j}))&(~isempty(string_list{i,j})), + uicontrol('Parent',fig_number, ... + 'Units','points', ... + 'Callback',callback_list{i,j}, ... + 'ListboxTop',0, ... + 'Position',[(2+(j-1)*(x_size+2)) (fig_size_y - i*(2+y_size)) x_size y_size], ... + 'String',string_list{i,j}, ... + 'Tag','Pushbutton1'); + end; + end; +end; diff --git a/SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/calib_gui.m b/SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/calib_gui.m new file mode 100755 index 0000000..62a45dd --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/calib_gui.m @@ -0,0 +1,81 @@ +fig_number = 1; + +n_row = 5; +n_col = 4; + +string_list = cell(n_row,n_col); +callback_list = cell(n_row,n_col); + +x_size = 85; +y_size = 20; + +title_figure = 'Camera calibration tool (2D rig)'; + +string_list{1,1} = 'Image names'; +string_list{1,2} = 'Read images'; +string_list{1,3} = 'Extract grid corners'; +%string_list{1,4} = 'Initialization'; +string_list{1,4} = 'Calibration'; +string_list{2,1} = 'Show Extrinsic'; +string_list{2,2} = 'Reproject on images'; +string_list{2,3} = 'Analyse error'; +string_list{2,4} = 'Recomp. corners'; +string_list{3,1} = 'Add/Suppress images'; +string_list{3,2} = 'Save'; +string_list{3,3} = 'Load'; +string_list{3,4} = 'Exit'; + +string_list{5,1} = 'Comp. Extrinsic'; +string_list{5,2} = 'Undistort image'; + + +callback_list{1,1} = 'data_calib;'; +callback_list{1,2} = 'ima_read_calib;'; +callback_list{1,3} = 'click_calib;'; +%callback_list{1,4} = 'init_calib_param;'; +callback_list{1,4} = 'go_calib_optim;'; +callback_list{2,1} = 'ext_calib;'; +callback_list{2,2} = 'reproject_calib;'; +callback_list{2,3} = 'analyse_error;'; +callback_list{2,4} = 'recomp_corner_calib;'; +callback_list{3,1} = 'add_suppress;'; +callback_list{3,2} = 'saving_calib;'; +callback_list{3,3} = 'loading_calib;'; +callback_list{3,4} = ['disp(''Bye. To run again, type calib_gui.''); close(' num2str(fig_number) ');']; + +callback_list{5,1} = 'extrinsic_computation;'; +callback_list{5,2} = 'undistort_image;'; + + +figure(fig_number); clf; +pos = get(fig_number,'Position'); + +fig_size_x = x_size*n_col+(n_col+1)*2; +fig_size_y = y_size*n_row+(n_row+1)*2; + +set(fig_number,'Units','points', ... + 'BackingStore','off', ... + 'Color',[0.8 0.8 0.8], ... + 'MenuBar','none', ... + 'Resize','off', ... + 'Name',title_figure, ... +'Position',[pos(1) pos(2) fig_size_x fig_size_y], ... +'NumberTitle','off'); %,'WindowButtonMotionFcn',['figure(' num2str(fig_number) ');']); + + +for i=n_row:-1:1, + for j = n_col:-1:1, + if (~isempty(callback_list{i,j}))&(~isempty(string_list{i,j})), + uicontrol('Parent',fig_number, ... + 'Units','points', ... + 'Callback',callback_list{i,j}, ... + 'ListboxTop',0, ... + 'Position',[(2+(j-1)*(x_size+2)) (fig_size_y - i*(2+y_size)) x_size y_size], ... + 'String',string_list{i,j}, ... + 'Tag','Pushbutton1'); + end; + end; +end; + + +clear callback_list string_list fig_number fig_size_x fig_size_y i j n_col n_row pos string_list title_figure x_size y_size diff --git a/SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/check_active_images.m b/SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/check_active_images.m new file mode 100755 index 0000000..4f09b62 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/check_active_images.m @@ -0,0 +1,14 @@ + +if ~exist('active_images'), + active_images = ones(1,n_ima); +end; +n_act = length(active_images); +if n_act < n_ima, + active_images = [active_images ones(1,n_ima-n_act)]; +else + if n_act > n_ima, + active_images = active_images(1:n_ima); + end; +end; + +ind_active = find(active_images); diff --git a/SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/check_convergence.m b/SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/check_convergence.m new file mode 100755 index 0000000..8602c39 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/check_convergence.m @@ -0,0 +1,17 @@ +%%% Replay the set of solution vectors: + +N_iter = size(param_list,2); + +for nn = 1:N_iter, + + solution = param_list(:,nn); + + extract_parameters; + comp_error_calib; + + ext_calib; + + drawnow; + + +end; diff --git a/SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/check_planarity.m b/SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/check_planarity.m new file mode 100755 index 0000000..be0410b --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/check_planarity.m @@ -0,0 +1,41 @@ +% Check the planarity of a structure: + +X = X_1; +N = size(X,2); + +%X(3,:) = 0.1*randn(1,N); + +om = rand(3,1); +T = 10*rand(3,1); +R = rodrigues(om); + +X = R * X + T*ones(1,N); + + + + + + +N = size(X,2); +X_mean = mean(X')'; + +Y = X - (X_mean*ones(1,N)); + +YY = Y*Y'; + +[U,S,V] = svd(YY); + +r = S(3,3)/S(2,2); + +% if r is less than 1e-4: + +R_transform = V'; +T_transform = -(V')*X_mean; + + +% Thresh for r: 1e-4 + +X_new = R_transform*X + T_transform*ones(1,N); + + +% If Xc = Rc * X_new + Tc, then Xc = Rc * R_transform * X + Tc + T_transform diff --git a/SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/click_calib.m b/SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/click_calib.m new file mode 100755 index 0000000..047cc7b --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/click_calib.m @@ -0,0 +1,99 @@ + +if ~exist('I_1'), + ima_read_calib; + if no_image_file, + disp('Cannot extract corners without images'); + return; + end; +end; + +check_active_images; + +%wintx = 10; % neigborhood of integration for +%winty = 10; % the corner finder + +fprintf(1,'\nExtraction of the grid corners on the images\n'); + +disp('Window size for corner finder (wintx and winty):'); +wintx = input('wintx ([] = 5) = '); +if isempty(wintx), wintx = 5; end; +wintx = round(wintx); +winty = input('winty ([] = 5) = '); +if isempty(winty), winty = 5; end; +winty = round(winty); + +fprintf(1,'Window size = %dx%d\n',2*wintx+1,2*winty+1); + +if ~exist('map'), map = gray(256); end; + + +disp('WARNING!!! Do not forget to change dX_default and dY_default in click_calib.m!!!') + + +% Default size of the pattern squares; + +% Setup of JY (old at Caltech) +dX_default = 21.9250/11; +dY_default = 18.1250/9; + +% Setup of JY (new at Intel) +dX_default = 1.9750; +dY_default = 1.9865; + + +% Setup of Luis and Enrico +dX_default = 67.7/16; +dY_default = 50.65/12; + + +% Setup of German +dX_default = 10.16; +dY_default = 10.16; + +% Setup of JY (new at Intel) +dX_default = 1.9750*2.54; +dY_default = 1.9865*2.54; + +% Setup of JY - 3D calibration rig at Intel (new at Intel) +dX_default = 3; +dY_default = 3; + +% Useful option to add images: +kk_first = input('Start image number ([]=1=first): '); + +if isempty(kk_first), kk_first = 1; end; + +for kk = kk_first:n_ima, + if active_images(kk), + click_ima_calib; + else + eval(['dX_' num2str(kk) ' = NaN;']); + eval(['dY_' num2str(kk) ' = NaN;']); + + eval(['wintx_' num2str(kk) ' = NaN;']); + eval(['winty_' num2str(kk) ' = NaN;']); + + eval(['x_' num2str(kk) ' = NaN*ones(2,1);']); + eval(['X_' num2str(kk) ' = NaN*ones(3,1);']); + + eval(['n_sq_x_' num2str(kk) ' = NaN;']); + eval(['n_sq_y_' num2str(kk) ' = NaN;']); + end; +end; + + + +string_save = 'save calib_data active_images ind_active wintx winty n_ima type_numbering N_slots first_num image_numbers format_image calib_name Hcal Wcal nx ny map dX_default dY_default dX dY'; + +for kk = 1:n_ima, + string_save = [string_save ' X_' num2str(kk) ' x_' num2str(kk) ' n_sq_x_' num2str(kk) ' n_sq_y_' num2str(kk) ' wintx_' num2str(kk) ' winty_' num2str(kk) ' dX_' num2str(kk) ' dY_' num2str(kk)]; +end; + +eval(string_save); + +disp('done'); + +return; + +go_calib_optim; + diff --git a/SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/click_calib3D.m b/SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/click_calib3D.m new file mode 100755 index 0000000..e761cd1 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/click_calib3D.m @@ -0,0 +1,79 @@ + +if ~exist('I_1'), + ima_read_calib; + if no_image_file, + disp('Cannot extract corners without images'); + return; + end; +end; + +%wintx = 10; % neigborhood of integration for +%winty = 10; % the corner finder + +fprintf(1,'\nExtraction of the grid corners on the images\n'); + +disp('Window size for corner finder (wintx and winty):'); +wintx = input('wintx ([] = 5) = '); +if isempty(wintx), wintx = 5; end; +wintx = round(wintx); +winty = input('winty ([] = 5) = '); +if isempty(winty), winty = 5; end; +winty = round(winty); + + +fprintf(1,'Window size = %dx%d\n',2*wintx+1,2*winty+1); + + +disp('WARNNG!!! Do not forget to change dX_default and dY_default in click_calib.m!!!') + + +% Default size of the pattern squares; + +% Setup of JY (old at Caltech) +dX_default = 21.9250/11; +dY_default = 18.1250/9; + +% Setup of JY (new at Intel) +dX_default = 1.9750; +dY_default = 1.9865; + + +% Setup of Luis and Enrico +dX_default = 67.7/16; +dY_default = 50.65/12; + + +% Setup of German +dX_default = 10.16; +dY_default = 10.16; + +% Setup of JY (new at Intel) +dX_default = 1.9750*2.54; +dY_default = 1.9865*2.54; + + +% Setup of JY - 3D calibration rig at Intel (new at Intel) +dX_default = 3; +dY_default = 3; + +% Useful option to add images: +kk_first = input('Start image number ([]=1=first): '); + +if isempty(kk_first), kk_first = 1; end; + +for kk = kk_first:n_ima, + click_ima_calib3D; %Simple version + %init_calib; %advanced vesion (more messy) +end; + + + +string_save = 'save calib_data wintx winty n_ima type_numbering N_slots first_num image_numbers format_image calib_name Hcal Wcal nx ny map dX_default dY_default dX dY'; + +for kk = 1:n_ima, + string_save = [string_save ' X_' num2str(kk) ' x_' num2str(kk) ' Hl_' num2str(kk) ' nl_sq_x_' num2str(kk) ' nl_sq_y_' num2str(kk) ' Hr_' num2str(kk) ' nr_sq_x_' num2str(kk) ' nr_sq_y_' num2str(kk)]; +end; + +eval(string_save); + +go_calib_optim3D; diff --git a/SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/click_ima_calib.m b/SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/click_ima_calib.m new file mode 100755 index 0000000..5197870 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/click_ima_calib.m @@ -0,0 +1,218 @@ + % Cleaned-up version of init_calib.m + + fprintf(1,'\nProcessing image %d...\n',kk); + + eval(['I = I_' num2str(kk) ';']); + + figure(2); + image(I); + colormap(map); + + title(['Click on the four extreme corners of the rectangular pattern... Image ' num2str(kk)]); + + disp('Click on the four extreme corners of the rectangular complete pattern...'); + + [x,y] = ginput3(4); + + [Xc,good,bad,type] = cornerfinder([x';y'],I,winty,wintx); % the four corners + + x = Xc(1,:)'; + y = Xc(2,:)'; + + [y,indy] = sort(y); + x = x(indy); + + if (x(2) > x(1)), + x4 = x(1);y4 = y(1); x3 = x(2); y3 = y(2); + else + x4 = x(2);y4 = y(2); x3 = x(1); y3 = y(1); + end; + if (x(3) > x(4)), + x2 = x(3);y2 = y(3); x1 = x(4); y1 = y(4); + else + x2 = x(4);y2 = y(4); x1 = x(3); y1 = y(3); + end; + + x = [x1;x2;x3;x4]; + y = [y1;y2;y3;y4]; + + + figure(2); hold on; + plot([x;x(1)],[y;y(1)],'g-'); + plot(x,y,'og'); + hx=text((x(4)+x(3))/2,(y(4)+y(3))/2 - 20,'X'); + set(hx,'color','g','Fontsize',14); + hy=text((x(4)+x(1))/2-20,(y(4)+y(1))/2,'Y'); + set(hy,'color','g','Fontsize',14); + hold off; + + + % Try to automatically count the number of squares in the grid + + n_sq_x1 = count_squares(I,x1,y1,x2,y2,wintx); + n_sq_x2 = count_squares(I,x3,y3,x4,y4,wintx); + n_sq_y1 = count_squares(I,x2,y2,x3,y3,wintx); + n_sq_y2 = count_squares(I,x4,y4,x1,y1,wintx); + + + + % If could not count the number of squares, enter manually + + if (n_sq_x1~=n_sq_x2)|(n_sq_y1~=n_sq_y2), + + + disp('Could not count the number of squares in the grid. Enter manually.'); + n_sq_x = input('Number of squares along the X direction ([]=10) = '); %6 + if isempty(n_sq_x), n_sq_x = 10; end; + n_sq_y = input('Number of squares along the Y direction ([]=10) = '); %6 + if isempty(n_sq_y), n_sq_y = 10; end; + + else + + n_sq_x = n_sq_x1; + n_sq_y = n_sq_y1; + + end; + + + % Enter the size of each square + + dX = input(['Size dX of each square along the X direction ([]=' num2str(dX_default) 'cm) = ']); + dY = input(['Size dY of each square along the Y direction ([]=' num2str(dY_default) 'cm) = ']); + if isempty(dX), dX = dX_default; else dX_default = dX; end; + if isempty(dY), dY = dY_default; else dY_default = dY; end; + + % Compute the inside points through computation of the planar homography (collineation) + + a00 = [x(1);y(1);1]; + a10 = [x(2);y(2);1]; + a11 = [x(3);y(3);1]; + a01 = [x(4);y(4);1]; + + + % Compute the planar collineation: (return the normalization matrix as well) + + [Homo,Hnorm,inv_Hnorm] = compute_homography ([a00 a10 a11 a01],[0 1 1 0;0 0 1 1;1 1 1 1]); + + + % Build the grid using the planar collineation: + + x_l = ((0:n_sq_x)'*ones(1,n_sq_y+1))/n_sq_x; + y_l = (ones(n_sq_x+1,1)*(0:n_sq_y))/n_sq_y; + pts = [x_l(:) y_l(:) ones((n_sq_x+1)*(n_sq_y+1),1)]'; + + XX = Homo*pts; + XX = XX(1:2,:) ./ (ones(2,1)*XX(3,:)); + + + % Complete size of the rectangle + + W = n_sq_x*dX; + L = n_sq_y*dY; + + + + + %%%%%%%%%%%%%%%%%%%%%%%% ADDITIONAL STUFF IN THE CASE OF HIGHLY DISTORTED IMAGES %%%%%%%%%%%%% + figure(2); + hold on; + plot(XX(1,:),XX(2,:),'r+'); + title('The red crosses should be close to the image corners'); + hold off; + + disp('If the guessed grid corners (red crosses on the image) are not close to the actual corners,'); + disp('it is necessary to enter an initial guess for the radial distortion factor kc (useful for subpixel detection)'); + quest_distort = input('Need of an initial guess for distortion? ([]=no, other=yes) '); + + quest_distort = ~isempty(quest_distort); + + if quest_distort, + % Estimation of focal length: + c_g = [size(I,2);size(I,1)]/2 + .5; + f_g = Distor2Calib(0,[[x(1) x(2) x(4) x(3)] - c_g(1);[y(1) y(2) y(4) y(3)] - c_g(2)],1,1,4,W,L,[-W/2 W/2 W/2 -W/2;L/2 L/2 -L/2 -L/2; 0 0 0 0],100,1,1); + f_g = mean(f_g); + script_fit_distortion; + end; + %%%%%%%%%%%%%%%%%%%%% END ADDITIONAL STUFF IN THE CASE OF HIGHLY DISTORTED IMAGES %%%%%%%%%%%%% + + + + + + Np = (n_sq_x+1)*(n_sq_y+1); + + disp('Corner extraction...'); + + grid_pts = cornerfinder(XX,I,winty,wintx); %%% Finds the exact corners at every points! + + + + %save all_corners x y grid_pts + + grid_pts = grid_pts - 1; % subtract 1 to bring the origin to (0,0) instead of (1,1) in matlab (not necessary in C) + + + % Global Homography from plane to pixel coordinates: + + + + + ind_corners = [1 n_sq_x+1 (n_sq_x+1)*n_sq_y+1 (n_sq_x+1)*(n_sq_y+1)]; % index of the 4 corners + ind_orig = (n_sq_x+1)*n_sq_y + 1; + xorig = grid_pts(1,ind_orig); + yorig = grid_pts(2,ind_orig); + dxpos = mean([grid_pts(:,ind_orig) grid_pts(:,ind_orig+1)]'); + dypos = mean([grid_pts(:,ind_orig) grid_pts(:,ind_orig-n_sq_x-1)]'); + + + x_box_kk = [grid_pts(1,:)-(wintx+.5);grid_pts(1,:)+(wintx+.5);grid_pts(1,:)+(wintx+.5);grid_pts(1,:)-(wintx+.5);grid_pts(1,:)-(wintx+.5)]; + y_box_kk = [grid_pts(2,:)-(winty+.5);grid_pts(2,:)-(winty+.5);grid_pts(2,:)+(winty+.5);grid_pts(2,:)+(winty+.5);grid_pts(2,:)-(winty+.5)]; + + + figure(3); + image(I); colormap(map); hold on; + plot(grid_pts(1,:)+1,grid_pts(2,:)+1,'r+'); + plot(x_box_kk+1,y_box_kk+1,'-b'); + plot(grid_pts(1,ind_corners)+1,grid_pts(2,ind_corners)+1,'mo'); + plot(xorig+1,yorig+1,'*m'); + h = text(xorig-15,yorig-15,'O'); + set(h,'Color','m','FontSize',14); + h2 = text(dxpos(1)-10,dxpos(2)-10,'dX'); + set(h2,'Color','g','FontSize',14); + h3 = text(dypos(1)-25,dypos(2)-3,'dY'); + set(h3,'Color','g','FontSize',14); + xlabel('Xc (in camera frame)'); + ylabel('Yc (in camera frame)'); + title('Extracted corners'); + zoom on; + drawnow; + hold off; + + + Xi = reshape(([0:n_sq_x]*dX)'*ones(1,n_sq_y+1),Np,1)'; + Yi = reshape(ones(n_sq_x+1,1)*[n_sq_y:-1:0]*dY,Np,1)'; + Zi = zeros(1,Np); + + Xgrid = [Xi;Yi;Zi]; + + + % All the point coordinates (on the image, and in 3D) - for global optimization: + + x = grid_pts; + X = Xgrid; + + + % Saves all the data into variables: + + eval(['dX_' num2str(kk) ' = dX;']); + eval(['dY_' num2str(kk) ' = dY;']); + + eval(['wintx_' num2str(kk) ' = wintx;']); + eval(['winty_' num2str(kk) ' = winty;']); + + eval(['x_' num2str(kk) ' = x;']); + eval(['X_' num2str(kk) ' = X;']); + + eval(['n_sq_x_' num2str(kk) ' = n_sq_x;']); + eval(['n_sq_y_' num2str(kk) ' = n_sq_y;']); + \ No newline at end of file diff --git a/SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/click_ima_calib3D.m b/SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/click_ima_calib3D.m new file mode 100755 index 0000000..7718268 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/click_ima_calib3D.m @@ -0,0 +1,482 @@ + % Cleaned-up version of init_calib.m + + eval(['I = I_' num2str(kk) ';']); + + figure(2); + image(I); + colormap(map); + + + + + + %%%%%%%%%%%%%%%%%%%%%%%%% LEFT PATTERN ACQUISITION %%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + + + title(['Click on the four extreme corners of the left rectangular pattern... Image ' num2str(kk)]); + + disp('Click on the four extreme corners of the left rectangular pattern...'); + + [x,y] = ginput3(4); + + [Xc,good,bad,type] = cornerfinder([x';y'],I,winty,wintx); % the four corners + + x = Xc(1,:)'; + y = Xc(2,:)'; + + [y,indy] = sort(y); + x = x(indy); + + if (x(2) > x(1)), + x4 = x(1);y4 = y(1); x3 = x(2); y3 = y(2); + else + x4 = x(2);y4 = y(2); x3 = x(1); y3 = y(1); + end; + if (x(3) > x(4)), + x2 = x(3);y2 = y(3); x1 = x(4); y1 = y(4); + else + x2 = x(4);y2 = y(4); x1 = x(3); y1 = y(3); + end; + + x = [x1;x2;x3;x4]; + y = [y1;y2;y3;y4]; + + + figure(2); hold on; + plot([x;x(1)],[y;y(1)],'g-'); + plot(x,y,'og'); + hx=text((x(4)+x(3))/2,(y(4)+y(3))/2 - 20,'X'); + set(hx,'color','g','Fontsize',14); + hy=text((x(4)+x(1))/2-20,(y(4)+y(1))/2,'Y'); + set(hy,'color','g','Fontsize',14); + hold off; + + drawnow; + + + % Try to automatically count the number of squares in the grid + + n_sq_x1 = count_squares(I,x1,y1,x2,y2,wintx); + n_sq_x2 = count_squares(I,x3,y3,x4,y4,wintx); + n_sq_y1 = count_squares(I,x2,y2,x3,y3,wintx); + n_sq_y2 = count_squares(I,x4,y4,x1,y1,wintx); + + + + % If could not count the number of squares, enter manually + + if (n_sq_x1~=n_sq_x2)|(n_sq_y1~=n_sq_y2), + + + disp('Could not count the number of squares in the grid. Enter manually.'); + n_sq_x = input('Number of squares along the X direction ([]=10) = '); %6 + if isempty(n_sq_x), n_sq_x = 10; end; + n_sq_y = input('Number of squares along the Y direction ([]=10) = '); %6 + if isempty(n_sq_y), n_sq_y = 10; end; + + else + + n_sq_x = n_sq_x1; + n_sq_y = n_sq_y1; + + end; + + + if 1, + % Enter the size of each square + + dX = input(['Size dX of each square along the X direction ([]=' num2str(dX_default) 'cm) = ']); + dY = input(['Size dY of each square along the Y direction ([]=' num2str(dY_default) 'cm) = ']); + if isempty(dX), dX = dX_default; else dX_default = dX; end; + if isempty(dY), dY = dY_default; else dY_default = dY; end; + + else + + dX = 3; + dY = 3; + + end; + + + % Compute the inside points through computation of the planar homography (collineation) + + a00 = [x(1);y(1);1]; + a10 = [x(2);y(2);1]; + a11 = [x(3);y(3);1]; + a01 = [x(4);y(4);1]; + + + % Compute the planart collineation: (return the normalization matrice as well) + + [Homo,Hnorm,inv_Hnorm] = compute_collineation (a00, a10, a11, a01); + + + % Build the grid using the planar collineation: + + x_l = ((0:n_sq_x)'*ones(1,n_sq_y+1))/n_sq_x; + y_l = (ones(n_sq_x+1,1)*(0:n_sq_y))/n_sq_y; + pts = [x_l(:) y_l(:) ones((n_sq_x+1)*(n_sq_y+1),1)]'; + + XX = Homo*pts; + XX = XX(1:2,:) ./ (ones(2,1)*XX(3,:)); + + + % Complete size of the rectangle + + W = n_sq_x*dX; + L = n_sq_y*dY; + + + + if 1, + %%%%%%%%%%%%%%%%%%%%%%%% ADDITIONAL STUFF IN THE CASE OF HIGHLY DISTORTED IMAGES %%%%%%%%%%%%% + figure(2); + hold on; + plot(XX(1,:),XX(2,:),'r+'); + title('The red crosses should be close to the image corners'); + hold off; + + disp('If the guessed grid corners (red crosses on the image) are not close to the actual corners,'); + disp('it is necessary to enter an initial guess for the radial distortion factor kc (useful for subpixel detection)'); + quest_distort = input('Need of an initial guess for distortion? ([]=no, other=yes) '); + + quest_distort = ~isempty(quest_distort); + + if quest_distort, + % Estimation of focal length: + c_g = [size(I,2);size(I,1)]/2 + .5; + f_g = Distor2Calib(0,[[x(1) x(2) x(4) x(3)] - c_g(1);[y(1) y(2) y(4) y(3)] - c_g(2)],1,1,4,W,L,[-W/2 W/2 W/2 -W/2;L/2 L/2 -L/2 -L/2; 0 0 0 0],100,1,1); + f_g = mean(f_g); + script_fit_distortion; + end; + %%%%%%%%%%%%%%%%%%%%% END ADDITIONAL STUFF IN THE CASE OF HIGHLY DISTORTED IMAGES %%%%%%%%%%%%% + end; + + + Np = (n_sq_x+1)*(n_sq_y+1); + + disp('Corner extraction...'); + + grid_pts = cornerfinder(XX,I,winty,wintx); %%% Finds the exact corners at every points! + + %save all_corners x y grid_pts + + grid_pts = grid_pts - 1; % subtract 1 to bring the origin to (0,0) instead of (1,1) in matlab (not necessary in C) + + + % Global Homography from plane to pixel coordinates: + + H_total = [1 0 -1 ; 0 1 -1 ; 0 0 1]*Homo*[1 0 0;0 -1 1;0 0 1]*[1/W 0 0 ; 0 1/L 0; 0 0 1]; + % WARNING!!! the first matrix (on the left side) takes care of the transformation of the pixel cooredinates by -1 (previous line) + % If it is not done, then this matrix should not appear (in C) + H_total = H_total / H_total(3,3); + + + ind_corners = [1 n_sq_x+1 (n_sq_x+1)*n_sq_y+1 (n_sq_x+1)*(n_sq_y+1)]; % index of the 4 corners + ind_orig = (n_sq_x+1)*n_sq_y + 1; + xorig = grid_pts(1,ind_orig); + yorig = grid_pts(2,ind_orig); + dxpos = mean([grid_pts(:,ind_orig) grid_pts(:,ind_orig+1)]'); + dypos = mean([grid_pts(:,ind_orig) grid_pts(:,ind_orig-n_sq_x-1)]'); + + + x_box_kk = [grid_pts(1,:)-(wintx+.5);grid_pts(1,:)+(wintx+.5);grid_pts(1,:)+(wintx+.5);grid_pts(1,:)-(wintx+.5);grid_pts(1,:)-(wintx+.5)]; + y_box_kk = [grid_pts(2,:)-(winty+.5);grid_pts(2,:)-(winty+.5);grid_pts(2,:)+(winty+.5);grid_pts(2,:)+(winty+.5);grid_pts(2,:)-(winty+.5)]; + + + figure(3); + image(I); colormap(map); hold on; + plot(grid_pts(1,:)+1,grid_pts(2,:)+1,'r+'); + plot(x_box_kk+1,y_box_kk+1,'-b'); + plot(grid_pts(1,ind_corners)+1,grid_pts(2,ind_corners)+1,'mo'); + plot(xorig+1,yorig+1,'*m'); + h = text(xorig-15,yorig-15,'O'); + set(h,'Color','m','FontSize',14); + h2 = text(dxpos(1)-10,dxpos(2)-10,'dX'); + set(h2,'Color','g','FontSize',14); + h3 = text(dypos(1)-25,dypos(2)-3,'dY'); + set(h3,'Color','g','FontSize',14); + xlabel('Xc (in camera frame)'); + ylabel('Yc (in camera frame)'); + title('Extracted corners'); + zoom on; + drawnow; + hold off; + + + Xi = reshape(([0:n_sq_x]*dX)'*ones(1,n_sq_y+1),Np,1)'; + Yi = reshape(ones(n_sq_x+1,1)*[n_sq_y:-1:0]*dY,Np,1)'; + Zi = zeros(1,Np); + + Xgrid = [Xi;Yi;Zi]; + + + % All the point coordinates (on the image, and in 3D) - for global optimization: + + x = grid_pts; + X = Xgrid; + + + % The left pannel info: + + xl = x; + Xl = X; + nl_sq_x = n_sq_x; + nl_sq_y = n_sq_y; + Hl = H_total; + + + + + + + %%%%%%%%%%%%%%%%%%%%%%%%% RIGHT PATTERN ACQUISITION %%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + + x1 = a10(1)/a10(3); + x4 = a11(1)/a11(3); + + y1 = a10(2)/a10(3); + y4 = a11(2)/a11(3); + + + figure(2); + hold on; + plot([x1 x4],[y1 y4],'c-'); + plot([x1 x4],[y1 y4],'co'); + hold off; + + title(['Click on the two remaining extreme corners of the right rectangular pattern... Image ' num2str(kk)]); + + disp('Click on the two remaining extreme corners of the right rectangular pattern...'); + + [x,y] = ginput3(2); + + [Xc,good,bad,type] = cornerfinder([x';y'],I,winty,wintx); % the four corners + + x = Xc(1,:)'; + y = Xc(2,:)'; + + [y,indy] = sort(y); + x = x(indy); + + x2 = x(2); + x3 = x(1); + + y2 = y(2); + y3 = y(1); + + + x = [x1;x2;x3;x4]; + y = [y1;y2;y3;y4]; + + figure(2); hold on; + plot([x;x(1)],[y;y(1)],'c-'); + plot(x,y,'oc'); + hx=text((x(4)+x(3))/2,(y(4)+y(3))/2 - 20,'X'); + set(hx,'color','c','Fontsize',14); + hy=text((x(4)+x(1))/2-20,(y(4)+y(1))/2,'Y'); + set(hy,'color','c','Fontsize',14); + hold off; + drawnow; + + + % Try to automatically count the number of squares in the grid + + n_sq_x1 = count_squares(I,x1,y1,x2,y2,wintx); + n_sq_x2 = count_squares(I,x3,y3,x4,y4,wintx); + n_sq_y1 = count_squares(I,x2,y2,x3,y3,wintx); + n_sq_y2 = count_squares(I,x4,y4,x1,y1,wintx); + + + + % If could not count the number of squares, enter manually + + if (n_sq_x1~=n_sq_x2)|(n_sq_y1~=n_sq_y2), + + + disp('Could not count the number of squares in the grid. Enter manually.'); + n_sq_x = input('Number of squares along the X direction ([]=10) = '); %6 + if isempty(n_sq_x), n_sq_x = 10; end; + n_sq_y = input('Number of squares along the Y direction ([]=10) = '); %6 + if isempty(n_sq_y), n_sq_y = 10; end; + + else + + n_sq_x = n_sq_x1; + n_sq_y = n_sq_y1; + + end; + + + if 1, + % Enter the size of each square + + dX = input(['Size dX of each square along the X direction ([]=' num2str(dX_default) 'cm) = ']); + dY = input(['Size dY of each square along the Y direction ([]=' num2str(dY_default) 'cm) = ']); + if isempty(dX), dX = dX_default; else dX_default = dX; end; + if isempty(dY), dY = dY_default; else dY_default = dY; end; + + else + + dX = 3; + dY = 3; + + end; + + + % Compute the inside points through computation of the planar homography (collineation) + + a00 = [x(1);y(1);1]; + a10 = [x(2);y(2);1]; + a11 = [x(3);y(3);1]; + a01 = [x(4);y(4);1]; + + + % Compute the planart collineation: (return the normalization matrice as well) + + [Homo,Hnorm,inv_Hnorm] = compute_collineation (a00, a10, a11, a01); + + + % Build the grid using the planar collineation: + + x_l = ((0:n_sq_x)'*ones(1,n_sq_y+1))/n_sq_x; + y_l = (ones(n_sq_x+1,1)*(0:n_sq_y))/n_sq_y; + pts = [x_l(:) y_l(:) ones((n_sq_x+1)*(n_sq_y+1),1)]'; + + XX = Homo*pts; + XX = XX(1:2,:) ./ (ones(2,1)*XX(3,:)); + + + % Complete size of the rectangle + + W = n_sq_x*dX; + L = n_sq_y*dY; + + + + if 1, + %%%%%%%%%%%%%%%%%%%%%%%% ADDITIONAL STUFF IN THE CASE OF HIGHLY DISTORTED IMAGES %%%%%%%%%%%%% + figure(2); + hold on; + plot(XX(1,:),XX(2,:),'r+'); + title('The red crosses should be close to the image corners'); + hold off; + + disp('If the guessed grid corners (red crosses on the image) are not close to the actual corners,'); + disp('it is necessary to enter an initial guess for the radial distortion factor kc (useful for subpixel detection)'); + quest_distort = input('Need of an initial guess for distortion? ([]=no, other=yes) '); + + quest_distort = ~isempty(quest_distort); + + if quest_distort, + % Estimation of focal length: + c_g = [size(I,2);size(I,1)]/2 + .5; + f_g = Distor2Calib(0,[[x(1) x(2) x(4) x(3)] - c_g(1);[y(1) y(2) y(4) y(3)] - c_g(2)],1,1,4,W,L,[-W/2 W/2 W/2 -W/2;L/2 L/2 -L/2 -L/2; 0 0 0 0],100,1,1); + f_g = mean(f_g); + script_fit_distortion; + end; + %%%%%%%%%%%%%%%%%%%%% END ADDITIONAL STUFF IN THE CASE OF HIGHLY DISTORTED IMAGES %%%%%%%%%%%%% + end; + + + Np = (n_sq_x+1)*(n_sq_y+1); + + disp('Corner extraction...'); + + grid_pts = cornerfinder(XX,I,winty,wintx); %%% Finds the exact corners at every points! + + %save all_corners x y grid_pts + + grid_pts = grid_pts - 1; % subtract 1 to bring the origin to (0,0) instead of (1,1) in matlab (not necessary in C) + + + % Global Homography from plane to pixel coordinates: + + H_total = [1 0 -1 ; 0 1 -1 ; 0 0 1]*Homo*[1 0 0;0 -1 1;0 0 1]*[1/W 0 0 ; 0 1/L 0; 0 0 1]; + % WARNING!!! the first matrix (on the left side) takes care of the transformation of the pixel cooredinates by -1 (previous line) + % If it is not done, then this matrix should not appear (in C) + H_total = H_total / H_total(3,3); + + + ind_corners = [1 n_sq_x+1 (n_sq_x+1)*n_sq_y+1 (n_sq_x+1)*(n_sq_y+1)]; % index of the 4 corners + ind_orig = (n_sq_x+1)*n_sq_y + 1; + xorig = grid_pts(1,ind_orig); + yorig = grid_pts(2,ind_orig); + dxpos = mean([grid_pts(:,ind_orig) grid_pts(:,ind_orig+1)]'); + dypos = mean([grid_pts(:,ind_orig) grid_pts(:,ind_orig-n_sq_x-1)]'); + + + x_box_kk = [grid_pts(1,:)-(wintx+.5);grid_pts(1,:)+(wintx+.5);grid_pts(1,:)+(wintx+.5);grid_pts(1,:)-(wintx+.5);grid_pts(1,:)-(wintx+.5)]; + y_box_kk = [grid_pts(2,:)-(winty+.5);grid_pts(2,:)-(winty+.5);grid_pts(2,:)+(winty+.5);grid_pts(2,:)+(winty+.5);grid_pts(2,:)-(winty+.5)]; + + + figure(3); + hold on; + plot(grid_pts(1,:)+1,grid_pts(2,:)+1,'r+'); + plot(x_box_kk+1,y_box_kk+1,'-b'); + plot(grid_pts(1,ind_corners)+1,grid_pts(2,ind_corners)+1,'mo'); + plot(xorig+1,yorig+1,'*m'); + h = text(xorig-15,yorig-15,'O'); + set(h,'Color','m','FontSize',14); + h2 = text(dxpos(1)-10,dxpos(2)-10,'dX'); + set(h2,'Color','g','FontSize',14); + h3 = text(dypos(1)-25,dypos(2)-3,'dY'); + set(h3,'Color','g','FontSize',14); + xlabel('Xc (in camera frame)'); + ylabel('Yc (in camera frame)'); + title('Extracted corners'); + zoom on; + drawnow; + hold off; + + + Xi = reshape(([0:n_sq_x]*dX)'*ones(1,n_sq_y+1),Np,1)'; + Yi = reshape(ones(n_sq_x+1,1)*[n_sq_y:-1:0]*dY,Np,1)'; + Zi = zeros(1,Np); + + Xgrid = [Xi;Yi;Zi]; + + + % All the point coordinates (on the image, and in 3D) - for global optimization: + + x = grid_pts; + X = Xgrid; + + + % The right pannel info: + + xr = x; + Xr = X; + nr_sq_x = n_sq_x; + nr_sq_y = n_sq_y; + Hr = H_total; + + + +%%%%%%%% REGROUP THE LEFT AND RIHT PATTERNS %%%%%%%%%%%%% + + +Xr2 = [0 0 1;0 1 0;-1 0 0]*Xr + [dX*nl_sq_x;0;0]*ones(1,length(Xr)); + + +x = [xl xr]; + +X = [Xl Xr2]; + + + + eval(['x_' num2str(kk) ' = x;']); + eval(['X_' num2str(kk) ' = X;']); + + eval(['nl_sq_x_' num2str(kk) ' = nl_sq_x;']); + eval(['nl_sq_y_' num2str(kk) ' = nl_sq_y;']); + + eval(['nr_sq_x_' num2str(kk) ' = nr_sq_x;']); + eval(['nr_sq_y_' num2str(kk) ' = nr_sq_y;']); + + % Save the global planar homography: + + eval(['Hl_' num2str(kk) ' = Hl;']); + eval(['Hr_' num2str(kk) ' = Hr;']); \ No newline at end of file diff --git a/SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/comp_distortion.m b/SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/comp_distortion.m new file mode 100755 index 0000000..a0f03de --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/comp_distortion.m @@ -0,0 +1,38 @@ +function [x_comp] = comp_distortion(x_dist,k2); + +% [x_comp] = comp_distortion(x_dist,k2); +% +% compensates the radial distortion of the camera +% on the image plane. +% +% x_dist : the image points got without considering the +% radial distortion. +% x : The image plane points after correction for the distortion +% +% x and x_dist are 2xN arrays +% +% NOTE : This compensation has to be done after the substraction +% of the center of projection, and division by the focal +% length. +% +% (do it up to a second order approximation) + +[two,N] = size(x_dist); + +if (two ~= 2 ), + error('ERROR : The dimension of the points should be 2xN'); +end; + +if length(k2) > 2, + [x_comp] = comp_distortion_oulu(x_dist,k2); +else + +radius_2= x_dist(1,:).^2 + x_dist(2,:).^2; +radial_distortion = 1 + ones(2,1)*(k2 * radius_2); +radius_2_comp = (x_dist(1,:).^2 + x_dist(2,:).^2) ./ radial_distortion(1,:); +radial_distortion = 1 + ones(2,1)*(k2 * radius_2_comp); +x_comp = x_dist ./ radial_distortion; + +end; + +%% Function completely checked : It works fine !!! \ No newline at end of file diff --git a/SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/comp_distortion2.m b/SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/comp_distortion2.m new file mode 100755 index 0000000..532ee9a --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/comp_distortion2.m @@ -0,0 +1,71 @@ +function [x_comp] = comp_distortion(x_dist,k2); + +% [x_comp] = comp_distortion(x_dist,k2); +% +% compensates the radial distortion of the camera +% on the image plane. +% +% x_dist : the image points got without considering the +% radial distortion. +% k2: Radial distortion factor +% +% x : The image plane points after correction for the distortion +% +% x and x_dist are 2xN arrays +% +% NOTE : This compensation has to be done after the substraction +% of the center of projection, and division by the focal +% length. +% +% Solve for cubic roots using method from Numerical Recipes in C 2nd Ed. +% pages 184-185. + + +% California Institute of Technology +% (c) Jean-Yves Bouguet - April 27th, 1998 + +% fully checked! JYB, april 27th, 1998 - 2am + +if k2 ~= 0, + +[two,N] = size(x_dist); + +if (two ~= 2 ), + error('ERROR : The dimension of the points should be 2xN'); +end; + + +ph = atan2(x_dist(2,:),x_dist(1,:)); + +Q = -1/(3*k2); +R = -x_dist(1,:)./(2*k2*cos(ph)); + +R2 = R.^2; +Q3 = Q^3; + + +if k2 < 0, + + % this works in all practical situations (it starts failing for very large + % values of k2) + + th = acos(R./sqrt(Q3)); + r = -2*sqrt(Q)*cos((th-2*pi)/3); + +else + + % note: this always works, even for ridiculous values of k2 + + A = (sqrt(R2-Q3)-R).^(1/3); + B = Q*(1./A); + r = (A+B); + +end; + +x_comp = [r.*cos(ph); r.*sin(ph)]; + +else + + x_comp = x_dist; + +end; diff --git a/SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/comp_distortion_oulu.m b/SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/comp_distortion_oulu.m new file mode 100755 index 0000000..67d02d5 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/comp_distortion_oulu.m @@ -0,0 +1,47 @@ +function [x] = comp_distortion_oulu(xd,k); + +%comp_distortion_oulu.m +% +%[x] = comp_distortion_oulu(xd,k) +% +%Compensates for radial and tangential distortion. Model From Oulu university. +%For more informatino about the distortion model, check the forward projection mapping function: +%project_points.m +% +%INPUT: xd: distorted (normalized) point coordinates in the image plane (2xN matrix) +% k: Distortion coefficients (radial and tangential) (4x1 vector) +% +%OUTPUT: x: undistorted (normalized) point coordinates in the image plane (2xN matrix) +% +%Method: Iterative method for compensation. +% +%NOTE: This compensation has to be done after the subtraction +% of the principal point, and division by the focal length. + + +if length(k) < 4, + + [x] = comp_distortion(xd,k); + +else + + + k1 = k(1); + k2 = k(2); + p1 = k(3); + p2 = k(4); + + x = xd; % initial guess + + for kk=1:5; + + r_2 = sum(x.^2); + k_radial = 1 + k1 * r_2 + k2 * r_2.^2; + delta_x = [2*p1*x(1,:).*x(2,:) + p2*(r_2 + 2*x(1,:).^2) ; + p1 * (r_2 + 2*x(2,:).^2)+2*p2*x(1,:).*x(2,:)]; + x = (xd - delta_x)./(ones(2,1)*k_radial); + + end; + +end; + diff --git a/SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/comp_error_calib.m b/SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/comp_error_calib.m new file mode 100755 index 0000000..f8d6fde --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/comp_error_calib.m @@ -0,0 +1,40 @@ +%%%%%%%%%%%%%%%%%%%% RECOMPUTES THE REPROJECTION ERROR %%%%%%%%%%%%%%%%%%%%%%%% + +check_active_images; + +% Reproject the patterns on the images, and compute the pixel errors: + +ex = []; % Global error vector +x = []; % Detected corners on the image plane +y = []; % Reprojected points + +for kk = 1:n_ima, + + eval(['omckk = omc_' num2str(kk) ';']); + eval(['Tckk = Tc_' num2str(kk) ';']); + + if active_images(kk) & (~isnan(omckk(1,1))), + + Rkk = rodrigues(omckk); + + eval(['y_' num2str(kk) ' = project2_oulu(X_' num2str(kk) ',Rkk,Tckk,fc,cc,kc);']); + + eval(['ex_' num2str(kk) ' = x_' num2str(kk) ' -y_' num2str(kk) ';']); + + eval(['x_kk = x_' num2str(kk) ';']); + + eval(['ex = [ex ex_' num2str(kk) '];']); + eval(['x = [x x_' num2str(kk) '];']); + eval(['y = [y y_' num2str(kk) '];']); + + else + + eval(['y_' num2str(kk) ' = NaN*ones(2,1);']); + + eval(['ex_' num2str(kk) ' = NaN*ones(2,1);']); + + end; + +end; + +err_std = std(ex')'; diff --git a/SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/compute_collineation.m b/SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/compute_collineation.m new file mode 100755 index 0000000..809c309 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/compute_collineation.m @@ -0,0 +1,66 @@ +function [H,Hnorm,inv_Hnorm] = compute_collineation (a00, a10, a11, a01); + +% new formalism using homographies + +a00 = a00 / a00(3); +a10 = a10 / a10(3); +a11 = a11 / a11(3); +a01 = a01 / a01(3); + + +% Prenormalization of point coordinates (very important): +% (Affine normalization) + +ax = [a00(1);a10(1);a11(1);a01(1)]; +ay = [a00(2);a10(2);a11(2);a01(2)]; + +mxx = mean(ax); +myy = mean(ay); +ax = ax - mxx; +ay = ay - myy; + +scxx = mean(abs(ax)); +scyy = mean(abs(ay)); + + +Hnorm = [1/scxx 0 -mxx/scxx;0 1/scyy -myy/scyy;0 0 1]; +inv_Hnorm = [scxx 0 mxx ; 0 scyy myy; 0 0 1]; + + +a00n = Hnorm*a00; +a10n = Hnorm*a10; +a11n = Hnorm*a11; +a01n = Hnorm*a01; + + +% Computation of the vanishing points: + +V1n = cross(cross(a00n,a10n),cross(a01n,a11n)); +V2n = cross(cross(a00n,a01n),cross(a10n,a11n)); + +V1 = inv_Hnorm*V1n; +V2 = inv_Hnorm*V2n; + + +% Normalizaion of the vanishing points: + +V1n = V1n/norm(V1n); +V2n = V2n/norm(V2n); + + +% Closed-form solution of the coefficients: + +alpha_x = (a10n(2)*a00n(1) - a10n(1)*a00n(2))/(V1n(2)*a10n(1)-V1n(1)*a10n(2)); + +alpha_y = (a01n(2)*a00n(1) - a01n(1)*a00n(2))/(V2n(2)*a01n(1)-V2n(1)*a01n(2)); + + +% Remaining Homography + +Hrem = [alpha_x*V1n alpha_y*V2n a00n]; + + +% Final homography: + +H = inv_Hnorm*Hrem; + diff --git a/SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/compute_extrinsic.m b/SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/compute_extrinsic.m new file mode 100755 index 0000000..4b4d7dd --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/compute_extrinsic.m @@ -0,0 +1,123 @@ +function [omckk,Tckk,Rckk,H,x,ex,JJ] = compute_extrinsic(x_kk,X_kk,fc,cc,kc,MaxIter,thresh_cond), + +%compute_extrinsic +% +%[omckk,Tckk,Rckk,H,x,ex] = compute_extrinsic(x_kk,X_kk,fc,cc,kc,refine) +% +%Computes the extrinsic parameters attached to a 3D structure X_kk given its projection +%on the image plane x_kk and the intrinsic camera parameters fc, cc and kc. +%Works with planar and non-planar structures. +% +%INPUT: x_kk: Feature locations on the images +% X_kk: Corresponding grid coordinates +% fc: Camera focal length +% cc: Principal point coordinates +% kc: Distortion coefficients +% refine: set to 1 for refining the extrinsic parameters iteratively +% [OPTIONAL: Default value: 1] +% +%OUTPUT: omckk: 3D rotation vector attached to the grid positions in space +% Tckk: 3D translation vector attached to the grid positions in space +% Rckk: 3D rotation matrices corresponding to the omc vectors +% H: Homography between points on the grid and points on the image plane (in pixel) +% This makes sense only if the planar that is used in planar. +% x: Reprojections of the points on the image plane +% ex: Reprojection error: ex = x_kk - x; +% +%Method: Computes the normalized point coordinates, then computes the 3D pose +% +%Important functions called within that program: +% +%normalize: Computes the normalize image point coordinates. +% +%pose3D: Computes the 3D pose of the structure given the normalized image projection. +% +%project_points.m: Computes the 2D image projections of a set of 3D points + + + +if nargin < 7, + thresh_cond = inf; +end; + + +if nargin < 6, + MaxIter = 20; +end; + + + +if nargin < 5, + kc = zeros(4,1); + if nargin < 4, + cc = zeros(2,1); + if nargin < 3, + fc = ones(2,1); + if nargin < 2, + error('Need 2D projections and 3D points (in compute_extrinsic.m)'); + return; + end; + end; + end; +end; + + +% Initialization: + +[omckk,Tckk,Rckk] = compute_extrinsic_init(x_kk,X_kk,fc,cc,kc); + +% Refinement: + +[omckk,Tckk,Rckk,JJ] = compute_extrinsic_refine(omckk,Tckk,x_kk,X_kk,fc,cc,kc,MaxIter,thresh_cond); + + +% computation of the homography (not useful in the end) + +H = [Rckk(:,1:2) Tckk]; + +% Computes the reprojection error in pixels: + +x = project_points(X_kk,omckk,Tckk,fc,cc,kc); + +ex = x_kk - x; + + +% Converts the homography in pixel units: + +KK = [fc(1) 0 cc(1);0 fc(2) cc(2); 0 0 1]; + +H = KK*H; + + + + +return; + + +% Test of compte extrinsic: + +Np = 4; +sx = 10; +sy = 10; +sz = 5; + +om = randn(3,1); +T = [0;0;100]; + +noise = 2/1000; + +XX = [sx*randn(1,Np);sy*randn(1,Np);sz*randn(1,Np)]; +xx = project_points(XX,om,T); + +xxn = xx + noise * randn(2,Np); + +[omckk,Tckk] = compute_extrinsic(xxn,XX); + +[om omckk om-omckk] +[T Tckk T-Tckk] + +figure(3); +plot(xx(1,:),xx(2,:),'r+'); +hold on; +plot(xxn(1,:),xxn(2,:),'g+'); +hold off; diff --git a/SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/compute_extrinsic_init.m b/SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/compute_extrinsic_init.m new file mode 100755 index 0000000..207ea30 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/compute_extrinsic_init.m @@ -0,0 +1,149 @@ +function [omckk,Tckk,Rckk] = compute_extrinsic_init(x_kk,X_kk,fc,cc,kc), + +%compute_extrinsic +% +%[omckk,Tckk,Rckk] = compute_extrinsic_init(x_kk,X_kk,fc,cc,kc) +% +%Computes the extrinsic parameters attached to a 3D structure X_kk given its projection +%on the image plane x_kk and the intrinsic camera parameters fc, cc and kc. +%Works with planar and non-planar structures. +% +%INPUT: x_kk: Feature locations on the images +% X_kk: Corresponding grid coordinates +% fc: Camera focal length +% cc: Principal point coordinates +% kc: Distortion coefficients +% +%OUTPUT: omckk: 3D rotation vector attached to the grid positions in space +% Tckk: 3D translation vector attached to the grid positions in space +% Rckk: 3D rotation matrices corresponding to the omc vectors +% +%Method: Computes the normalized point coordinates, then computes the 3D pose +% +%Important functions called within that program: +% +%normalize: Computes the normalize image point coordinates. +% +%pose3D: Computes the 3D pose of the structure given the normalized image projection. +% +%project_points.m: Computes the 2D image projections of a set of 3D points + + + + +if nargin < 5, + kc = zeros(4,1); + if nargin < 4, + cc = zeros(2,1); + if nargin < 3, + fc = ones(2,1); + if nargin < 2, + error('Need 2D projections and 3D points (in compute_extrinsic.m)'); + return; + end; + end; + end; +end; + + + +% Compute the normalized coordinates: + +xn = normalize(x_kk,fc,cc,kc); + + + +Np = size(xn,2); + +%% Check for planarity of the structure: + +X_mean = mean(X_kk')'; + +Y = X_kk - (X_mean*ones(1,Np)); + +YY = Y*Y'; + +[U,S,V] = svd(YY); + +r = S(3,3)/S(2,2); + +if (r < 1e-3)|(Np < 6), %1e-3, %1e-4, %norm(X_kk(3,:)) < eps, % Test of planarity + + %fprintf(1,'Planar structure detected: r=%f\n',r); + + % Transform the plane to bring it in the Z=0 plane: + + R_transform = V'; + + if det(R_transform) < 0, R_transform = -R_transform; end; + + T_transform = -(R_transform)*X_mean; + + X_new = R_transform*X_kk + T_transform*ones(1,Np); + + + % Compute the planar homography: + + H = compute_homography (xn,X_new(1:2,:)); + + % De-embed the motion parameters from the homography: + + sc = mean([norm(H(:,1));norm(H(:,2))]); + + H = H/sc; + + omckk = rodrigues([H(:,1:2) cross(H(:,1),H(:,2))]); + Rckk = rodrigues(omckk); + Tckk = H(:,3); + + %If Xc = Rckk * X_new + Tckk, then Xc = Rckk * R_transform * X_kk + Tckk + T_transform + + Tckk = Tckk + Rckk* T_transform; + Rckk = Rckk * R_transform; + + omckk = rodrigues(Rckk); + Rckk = rodrigues(omckk); + + +else + + %fprintf(1,'Non planar structure detected: r=%f\n',r); + + % Computes an initial guess for extrinsic parameters (works for general 3d structure, not planar!!!): + % The DLT method is applied here!! + + J = zeros(2*Np,12); + + xX = (ones(3,1)*xn(1,:)).*X_kk; + yX = (ones(3,1)*xn(2,:)).*X_kk; + + J(1:2:end,[1 4 7]) = -X_kk'; + J(2:2:end,[2 5 8]) = X_kk'; + J(1:2:end,[3 6 9]) = xX'; + J(2:2:end,[3 6 9]) = -yX'; + J(1:2:end,12) = xn(1,:)'; + J(2:2:end,12) = -xn(2,:)'; + J(1:2:end,10) = -ones(Np,1); + J(2:2:end,11) = ones(Np,1); + + JJ = J'*J; + [U,S,V] = svd(JJ); + + RR = reshape(V(1:9,12),3,3); + + if det(RR) < 0, + V(:,12) = -V(:,12); + RR = -RR; + end; + + [Ur,Sr,Vr] = svd(RR); + + Rckk = Ur*Vr'; + + sc = norm(V(1:9,12)) / norm(Rckk(:)); + Tckk = V(10:12,12)/sc; + + omckk = rodrigues(Rckk); + Rckk = rodrigues(omckk); + +end; diff --git a/SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/compute_extrinsic_refine.m b/SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/compute_extrinsic_refine.m new file mode 100755 index 0000000..69474c4 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/compute_extrinsic_refine.m @@ -0,0 +1,110 @@ +function [omckk,Tckk,Rckk,JJ] = compute_extrinsic_refine(omc_init,Tc_init,x_kk,X_kk,fc,cc,kc,MaxIter,thresh_cond), + +%compute_extrinsic +% +%[omckk,Tckk,Rckk] = compute_extrinsic_refine(x_kk,X_kk,fc,cc,kc,MaxIter) +% +%Computes the extrinsic parameters attached to a 3D structure X_kk given its projection +%on the image plane x_kk and the intrinsic camera parameters fc, cc and kc. +%Works with planar and non-planar structures. +% +%INPUT: x_kk: Feature locations on the images +% X_kk: Corresponding grid coordinates +% fc: Camera focal length +% cc: Principal point coordinates +% kc: Distortion coefficients +% MaxIter: Maximum number of iterations +% +%OUTPUT: omckk: 3D rotation vector attached to the grid positions in space +% Tckk: 3D translation vector attached to the grid positions in space +% Rckk: 3D rotation matrices corresponding to the omc vectors + +% +%Method: Computes the normalized point coordinates, then computes the 3D pose +% +%Important functions called within that program: +% +%normalize: Computes the normalize image point coordinates. +% +%pose3D: Computes the 3D pose of the structure given the normalized image projection. +% +%project_points.m: Computes the 2D image projections of a set of 3D points + + +if nargin < 9, + thresh_cond = inf; +end; + + +if nargin < 8, + MaxIter = 20; +end; + + +if nargin < 7, + kc = zeros(4,1); + if nargin < 6, + cc = zeros(2,1); + if nargin < 5, + fc = ones(2,1); + if nargin < 4, + error('Need 2D projections and 3D points (in compute_extrinsic_refine.m)'); + return; + end; + end; + end; +end; + + +% Initialization: + +omckk = omc_init; +Tckk = Tc_init; + + +% Final optimization (minimize the reprojection error in pixel): +% through Gradient Descent: + +param = [omckk;Tckk]; + +change = 1; + +iter = 0; + +%keyboard; + +%fprintf(1,'Gradient descent iterations: '); + +while (change > 1e-10)&(iter < MaxIter), + + %fprintf(1,'%d...',iter+1); + + [x,dxdom,dxdT] = project_points(X_kk,omckk,Tckk,fc,cc,kc); + + ex = x_kk - x; + + %keyboard; + + JJ = [dxdom dxdT]; + + if cond(JJ) > thresh_cond, + change = 0; + else + + JJ2 = JJ'*JJ; + + param_innov = inv(JJ2)*(JJ')*ex(:); + param_up = param + param_innov; + change = norm(param_innov)/norm(param_up); + param = param_up; + iter = iter + 1; + + omckk = param(1:3); + Tckk = param(4:6); + end; + +end; + +%fprintf(1,'\n'); + +Rckk = rodrigues(omckk); diff --git a/SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/compute_homography.m b/SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/compute_homography.m new file mode 100755 index 0000000..fcc9003 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/compute_homography.m @@ -0,0 +1,163 @@ +function [H,Hnorm,inv_Hnorm] = compute_homography (m,M); + +%compute_homography +% +%[H,Hnorm,inv_Hnorm] = compute_homography (m,M) +% +%Computes the planar homography between the point coordinates on the plane (M) and the image +%point coordinates (m). +% +%INPUT: m: homogeneous coordinates in the image plane (3xN matrix) +% M: homogeneous coordinates in the plane in 3D (3xN matrix) +% +%OUTPUT: H: Homography matrix (3x3 homogeneous matrix) +% Hnorm: Normlization matrix used on the points before homography computation +% (useful for numerical stability is points in pixel coordinates) +% inv_Hnorm: The inverse of Hnorm +% +%Definition: m ~ H*M where "~" means equal up to a non zero scalar factor. +% +%Method: First computes an initial guess for the homography through quasi-linear method. +% Then, if the total number of points is larger than 4, optimize the solution by minimizing +% the reprojection error (in the least squares sense). +% +% +%Important functions called within that program: +% +%comp_distortion_oulu: Undistorts pixel coordinates. +% +%compute_homography.m: Computes the planar homography between points on the grid in 3D, and the image plane. +% +%project_points.m: Computes the 2D image projections of a set of 3D points, and also returns te Jacobian +% matrix (derivative with respect to the intrinsic and extrinsic parameters). +% This function is called within the minimization loop. + + + + +Np = size(m,2); + +if size(m,1)<3, + m = [m;ones(1,Np)]; +end; + +if size(M,1)<3, + M = [M;ones(1,Np)]; +end; + + +m = m ./ (ones(3,1)*m(3,:)); +M = M ./ (ones(3,1)*M(3,:)); + +% Prenormalization of point coordinates (very important): +% (Affine normalization) + +ax = m(1,:); +ay = m(2,:); + +mxx = mean(ax); +myy = mean(ay); +ax = ax - mxx; +ay = ay - myy; + +scxx = mean(abs(ax)); +scyy = mean(abs(ay)); + + +Hnorm = [1/scxx 0 -mxx/scxx;0 1/scyy -myy/scyy;0 0 1]; +inv_Hnorm = [scxx 0 mxx ; 0 scyy myy; 0 0 1]; + +mn = Hnorm*m; + +% Compute the homography between m and mn: + +% Build the matrix: + +L = zeros(2*Np,9); + +L(1:2:2*Np,1:3) = M'; +L(2:2:2*Np,4:6) = M'; +L(1:2:2*Np,7:9) = -((ones(3,1)*mn(1,:)).* M)'; +L(2:2:2*Np,7:9) = -((ones(3,1)*mn(2,:)).* M)'; + +if Np > 4, + L = L'*L; +end; + +[U,S,V] = svd(L); + +hh = V(:,9); +hh = hh/hh(9); + +Hrem = reshape(hh,3,3)'; +%Hrem = Hrem / Hrem(3,3); + +% Final homography: + +H = inv_Hnorm*Hrem; + + +%%% Homography refinement if there are more than 4 points: + +if Np > 4, + + % Final refinement: + + hhv = reshape(H',9,1); + hhv = hhv(1:8); + + for iter=1:10, + + mrep = H * M; + + J = zeros(2*Np,8); + + MMM = (M ./ (ones(3,1)*mrep(3,:))); + + J(1:2:2*Np,1:3) = -MMM'; + J(2:2:2*Np,4:6) = -MMM'; + + mrep = mrep ./ (ones(3,1)*mrep(3,:)); + + m_err = m(1:2,:) - mrep(1:2,:); + m_err = m_err(:); + + MMM2 = (ones(3,1)*mrep(1,:)) .* MMM; + MMM3 = (ones(3,1)*mrep(2,:)) .* MMM; + + J(1:2:2*Np,7:8) = MMM2(1:2,:)'; + J(2:2:2*Np,7:8) = MMM3(1:2,:)'; + + MMM = (M ./ (ones(3,1)*mrep(3,:)))'; + + hh_innov = inv(J'*J)*J'*m_err; + + hhv_up = hhv - hh_innov; + + H_up = reshape([hhv_up;1],3,3)'; + + %norm(m_err) + %norm(hh_innov) + + hhv = hhv_up; + H = H_up; + + end; + +end; + + + + + +return; + +%test of Jacobian + +mrep = H*M; +mrep = mrep ./ (ones(3,1)*mrep(3,:)); + +m_err = mrep(1:2,:) - m(1:2,:); +figure(8); +plot(m_err(1,:),m_err(2,:),'r+'); +std(m_err') diff --git a/SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/convert_oulu.m b/SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/convert_oulu.m new file mode 100755 index 0000000..726806e --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/convert_oulu.m @@ -0,0 +1,35 @@ +%% Converts data file from oulu to mine: + +load cademo, +n_ima = 0; + +no_error = 1; + +ii = 1; + +while no_error, + + dataname = ['data' num2str(ii)]; + + if exist(dataname), + + n_ima = n_ima +1; + + eval(['x_' num2str(ii) '= ' dataname '(:,4:5)'';']) + eval(['X_' num2str(ii) '= ' dataname '(:,1:3)'';']) + + else + no_error = 0; + end; + + ii = ii + 1; + +end; + +nx = 500; +ny = 500; + +no_image = 1; +no_grid = 1; + +save data n_ima x_1 X_1 x_2 X_2 x_3 X_3 nx ny no_image no_grid diff --git a/SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/cornerfinder.m b/SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/cornerfinder.m new file mode 100755 index 0000000..9bfa51f --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/cornerfinder.m @@ -0,0 +1,215 @@ +function [xc,good,bad,type] = cornerfinder(xt,I,wintx,winty,wx2,wy2); + +%[xc] = cornerfinder(xt,I); +% +%Finds the sub-pixel corners on the image I with initial guess xt +%xt and xc are 2xN matrices. The first component is the x coordinate +%(horizontal) and the second component is the y coordinate (vertical) +% +%Based on Harris corner finder method +% +%Finds corners to a precision below .1 pixel! +%Oct. 14th, 1997 - UPDATED to work with vertical and horizontal edges as well!!! +%Sept 1998 - UPDATED to handle diverged points: we keep the original points +%good is a binary vector indicating wether a feature point has been properly +%found. +% +%Add a zero zone of size wx2,wy2 +%July 15th, 1999 - Bug on the mask building... fixed + change to Gaussian mask with higher +%resolution and larger number of iterations. + + +% California Institute of Technology +% (c) Jean-Yves Bouguet -- Oct. 14th, 1997 + + + +line_feat = 1; % set to 1 to allow for extraction of line features. + +xt = xt'; +xt = fliplr(xt); + + +if nargin < 4, + winty = 5; + if nargin < 3, + wintx = 5; + end; +end; + + +if nargin < 6, + wx2 = -1; + wy2 = -1; +end; + + +%mask = ones(2*wintx+1,2*winty+1); +mask = exp(-((-wintx:wintx)'/(wintx)).^2) * exp(-((-winty:winty)/(winty)).^2); + + +if (wx2>0) & (wy2>0), + if ((wintx - wx2)>=2)&((winty - wy2)>=2), + mask(wintx+1-wx2:wintx+1+wx2,winty+1-wy2:winty+1+wy2)= zeros(2*wx2+1,2*wy2+1); + end; +end; + +offx = [-wintx:wintx]'*ones(1,2*winty+1); +offy = ones(2*wintx+1,1)*[-winty:winty]; + +resolution = 0.005; + +MaxIter = 10; + +[nx,ny] = size(I); +N = size(xt,1); + +xc = xt; % first guess... they don't move !!! + +type = zeros(1,N); + + +for i=1:N, + + v_extra = resolution + 1; % just larger than resolution + + compt = 0; % no iteration yet + + while (norm(v_extra) > resolution) & (compt 0, % the sub pixel + vIx = [itIx 1-itIx 0]'; % accuracy. + else + vIx = [0 1+itIx -itIx]'; + end; + if itIy > 0, + vIy = [itIy 1-itIy 0]; + else + vIy = [0 1+itIy -itIy]; + end; + + + % What if the sub image is not in? + + if (crIx-wintx-2 < 1), xmin=1; xmax = 2*wintx+5; + elseif (crIx+wintx+2 > nx), xmax = nx; xmin = nx-2*wintx-4; + else + xmin = crIx-wintx-2; xmax = crIx+wintx+2; + end; + + if (crIy-winty-2 < 1), ymin=1; ymax = 2*winty+5; + elseif (crIy+winty+2 > ny), ymax = ny; ymin = ny-2*winty-4; + else + ymin = crIy-winty-2; ymax = crIy+winty+2; + end; + + + SI = I(xmin:xmax,ymin:ymax); % The necessary neighborhood + SI = conv2(conv2(SI,vIx,'same'),vIy,'same'); + SI = SI(2:2*wintx+4,2:2*winty+4); % The subpixel interpolated neighborhood + [gy,gx] = gradient(SI); % The gradient image + gx = gx(2:2*wintx+2,2:2*winty+2); % extraction of the useful parts only + gy = gy(2:2*wintx+2,2:2*winty+2); % of the gradients + + px = cIx + offx; + py = cIy + offy; + + gxx = gx .* gx .* mask; + gyy = gy .* gy .* mask; + gxy = gx .* gy .* mask; + + + bb = [sum(sum(gxx .* px + gxy .* py)); sum(sum(gxy .* px + gyy .* py))]; + + a = sum(sum(gxx)); + b = sum(sum(gxy)); + c = sum(sum(gyy)); + + dt = a*c - b^2; + + xc2 = [c*bb(1)-b*bb(2) a*bb(2)-b*bb(1)]/dt; + + + %keyboard; + + if line_feat, + + G = [a b;b c]; + [U,S,V] = svd(G); + + %keyboard; + + % If non-invertible, then project the point onto the edge orthogonal: + + if (S(1,1)/S(2,2) > 50), + % projection operation: + xc2 = xc2 + sum((xc(i,:)-xc2).*(V(:,2)'))*V(:,2)'; + type(i) = 1; + end; + + end; + + + %keyboard; + +% G = [a b;b c]; +% [U,S,V] = svd(G); + + +% if S(1,1)/S(2,2) > 150, +% bb2 = U'*bb; +% xc2 = (V*[bb2(1)/S(1,1) ;0])'; +% else +% xc2 = [c*bb(1)-b*bb(2) a*bb(2)-b*bb(1)]/dt; +% end; + + + %if (abs(a)> 50*abs(c)), +% xc2 = [(c*bb(1)-b*bb(2))/dt xc(i,2)]; +% elseif (abs(c)> 50*abs(a)) +% xc2 = [xc(i,1) (a*bb(2)-b*bb(1))/dt]; +% else +% xc2 = [c*bb(1)-b*bb(2) a*bb(2)-b*bb(1)]/dt; +% end; + + %keyboard; + + v_extra = xc(i,:) - xc2; + + xc(i,:) = xc2; + +% keyboard; + + compt = compt + 1; + + end +end; + + +% check for points that diverge: + +delta_x = xc(:,1) - xt(:,1); +delta_y = xc(:,2) - xt(:,2); + +%keyboard; + + +bad = (abs(delta_x) > wintx) | (abs(delta_y) > winty); +good = ~bad; +in_bad = find(bad); + +% For the diverged points, keep the original guesses: + +xc(in_bad,:) = xt(in_bad,:); + +xc = fliplr(xc); +xc = xc'; + +bad = bad'; +good = good'; diff --git a/SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/count_squares.m b/SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/count_squares.m new file mode 100755 index 0000000..0e226c0 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/count_squares.m @@ -0,0 +1,74 @@ +function ns = count_squares(I,x1,y1,x2,y2,win); + +%keyboard; + +[ny,nx] = size(I); + +lambda = [y1 - y2;x2 - x1;x1*y2 - x2*y1]; + +lambda = 1/sqrt(lambda(1)^2 + lambda(2)^2) * lambda; + +l1 = lambda + [0;0;win]; +l2 = lambda - [0;0;win]; + + +dx = x2-x1; +dy = y2 - y1; + + +if abs(dx) > abs(dy), + + if x2 > x1, + xs = x1:x2; + else + xs = x1:-1:x2; + end; + + ys = -(lambda(3) + lambda(1)*xs)/lambda(2); + +else + + if y2 > y1, + ys = y1:y2; + else + ys = y1:-1:y2; + end; + xs = -(lambda(3) + lambda(2)*ys)/lambda(1); + +end; + + + + Np = length(xs); + + xs_mat = ones(2*win + 1,1)*xs; + ys_mat = ones(2*win + 1,1)*ys; + + win_mat = (-win:win)'*ones(1,Np); + + + xs_mat2 = round(xs_mat - win_mat * lambda(1)); + ys_mat2 = round(ys_mat - win_mat * lambda(2)); + + ind_mat = (xs_mat2 - 1) * ny + ys_mat2; + + ima_patch = zeros(2*win + 1,Np); + + ima_patch(:) = I(ind_mat(:)); + + %ima2 = ima_patch(:,win+1:end-win); + + filtk = [ones(win,Np);zeros(1,Np);-ones(win,Np)]; + + out_f = sum(filtk.*ima_patch); + + out_f_f = conv2(out_f,[1/4 1/2 1/4],'same'); + + out_f_f = out_f_f(win+1:end-win); + + ns = length(find(((out_f_f(2:end)>=0)&(out_f_f(1:end-1)<0)) | ((out_f_f(2:end)<=0)&(out_f_f(1:end-1)>0))))+1; + + + + +return; diff --git a/SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/data_calib.m b/SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/data_calib.m new file mode 100755 index 0000000..318ec15 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/data_calib.m @@ -0,0 +1,89 @@ +%%% This script alets the user enter the name of the images (base name, numbering scheme,... + +dir; + +%disp('Camera Calibration using multiple images of a planar checkerboard pattern'); +%disp('Model: 2 focals, 2 radial dist. coeff., 2 tangential dist. coeff. and principle point'); +%disp(' => 8DOF intrinsic model ([Heikkila and Silven, University of Oulu])'); + +fprintf(1,'\n'); +calib_name = input('Basename camera calibration images (without number nor suffix): ','s'); + +format_image = '0'; + +while format_image == '0', + + format_image = input('Image format: ([]=''r''=''ras'', ''b''=''bmp'', ''t''=''tif'', ''p''=''pgm'', ''j''=''jpg'') ','s'); + + if isempty(format_image), + format_image = 'ras'; + end; + + if lower(format_image(1)) == 'b', + format_image = 'bmp'; + else + if lower(format_image(1)) == 't', + format_image = 'tif'; + else + if lower(format_image(1)) == 'p', + format_image = 'pgm'; + else + if lower(format_image(1)) == 'j', + format_image = 'jpg'; + else + if lower(format_image(1)) == 'r', + format_image = 'ras'; + else + disp('Invalid image format'); + format_image = '0'; % Ask for format once again + end; + end; + end; + end; + end; + +end; + + +n_ima = 1000; +while n_ima > 30, + n_ima = input('Number of calibration images: '); + n_ima = round(n_ima); +end; + +type_numbering = input('Type of numbering (ex: []=4,other=04): '); + +type_numbering = ~isempty(type_numbering); + +if type_numbering, + + N_slots = input('Number of spaces for numbers? (ex: 2 -> 04, 3 -> 004), ([]=3) '); + + if isempty(N_slots), N_slots = 3; end; + +else + + N_slots = 1; % not used anyway, but useful for saving + +end; + + +first_num = input('First image number? (0,1,2...) ([]=0) '); + +if isempty(first_num), first_num = 0; end; + +image_numbers = first_num:n_ima-1+first_num; + + +%%% By default, all the images are active for calibration: + +active_images = ones(1,n_ima); + +%string_save = 'save calib_data n_ima type_numbering N_slots image_numbers format_image calib_name first_num'; + +%eval(string_save); + +% Reading images: + +ima_read_calib; + diff --git a/SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/error_analysis.m b/SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/error_analysis.m new file mode 100755 index 0000000..85feac5 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/error_analysis.m @@ -0,0 +1,182 @@ +%%% ERROR_ANALYSIS +%%% This simulation helps coputing the acturacies of calibration +%%% Run it after the main calibration + + + +N_runs = 200; + +%N_ima_active = 4; + +saving = 1; + +if 1, %~exist('fc_list'), % initialization + + % Initialization: + + load Calib_Results; + check_active_images; + + fc_list = []; + cc_list = []; + kc_list = []; + active_images_list = []; + + + for kk=1:n_ima, + + eval(['omc_list_' num2str(kk) ' = [];']); + eval(['Tc_list_' num2str(kk) ' = [];']); + + end; + + %sx = median(abs(ex(1,:)))*1.4836; + %sy = median(abs(ex(2,:)))*1.4836; + + sx = std(ex(1,:)); + sy = std(ex(2,:)); + + % Saving the feature locations: + + for kk = 1:n_ima, + + eval(['x_save_' num2str(kk) ' = x_' num2str(kk) ';']); + eval(['y_save_' num2str(kk) ' = y_' num2str(kk) ';']); + + end; + + active_images_save = active_images; + ind_active_save = ind_active; + + fc_save = fc; + cc_save = cc; + kc_save = kc; + KK_save = KK; + + +end; + + + + +%%% The main loop: + + +for ntrial = 1:N_runs, + + fprintf(1,'\nRun number: %d\n',ntrial); + fprintf(1, '----------\n'); + + for kk = 1:n_ima, + + eval(['y_kk = y_save_' num2str(kk) ';']) + + if active_images(kk) & ~isnan(y_kk(1,1)), + + Nkk = size(y_kk,2); + + x_kk_new = y_kk + [sx * randn(1,Nkk);sy*randn(1,Nkk)]; + + eval(['x_' num2str(kk) ' = x_kk_new;']); + + end; + + end; + + N_active = length(ind_active_save); + junk = randn(1,N_active); + [junk,junk2] = sort(junk); + + active_images = zeros(1,n_ima); + active_images(ind_active_save(junk2(1:N_ima_active))) = ones(1,N_ima_active); + + fc = fc_save; + cc = cc_save; + kc = kc_save; + KK = KK_save; + + go_calib_optim; + + fc_list = [fc_list fc]; + cc_list = [cc_list cc]; + kc_list = [kc_list kc]; + active_images_list = [active_images_list active_images']; + + for kk=1:n_ima, + + eval(['omc_list_' num2str(kk) ' = [ omc_list_' num2str(kk) ' omc_' num2str(kk) ' ];']); + eval(['Tc_list_' num2str(kk) ' = [ Tc_list_' num2str(kk) ' Tc_' num2str(kk) ' ];']); + + end; + +end; + + + + +if 0, + +% Restoring the feature locations: + +for kk = 1:n_ima, + + eval(['x_' num2str(kk) ' = x_save_' num2str(kk) ';']); + +end; + +fprintf(1,'\nFinal run (with the real data)\n'); +fprintf(1, '------------------------------\n'); + +active_images = active_images_save; +ind_active = ind_active_save; + +go_calib_optim; + +fc_list = [fc_list fc]; +cc_list = [cc_list cc]; +kc_list = [kc_list kc]; +active_images_list = [active_images_list active_images']; + +for kk=1:n_ima, + + eval(['omc_list_' num2str(kk) ' = [ omc_list_' num2str(kk) ' omc_' num2str(kk) ' ];']); + eval(['Tc_list_' num2str(kk) ' = [ Tc_list_' num2str(kk) ' Tc_' num2str(kk) ' ];']); + +end; + +end; + + + + + +if saving, + +disp(['Save Calibration accuracy results under Calib_Accuracies_' num2str(N_ima_active) '.mat']); + +string_save = ['save Calib_Accuracies_' num2str(N_ima_active) ' active_images n_ima N_ima_active N_runs active_images_list fc cc kc fc_list cc_list kc_list']; + +for kk = 1:n_ima, + string_save = [string_save ' Tc_list_' num2str(kk) ' omc_list_' num2str(kk) ' Tc_' num2str(kk) ' omc_' num2str(kk) ]; +end; + +eval(string_save); + +end; + + +return; + +std(fc_list') + +std(cc_list') + +std(kc_list') + +for kk = 1:n_ima, + + eval(['std(Tc_list_' num2str(kk) ''')']) + +end; + + diff --git a/SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/ext_calib.m b/SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/ext_calib.m new file mode 100755 index 0000000..d41d068 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/ext_calib.m @@ -0,0 +1,130 @@ + +%%%%%%%%%%%%%%%%%%%% SHOW EXTRINSIC RESULTS %%%%%%%%%%%%%%%%%%%%%%%% + +check_active_images; + +if ~exist(['omc_' num2str(ind_active(1))]), + fprintf(1,'Need to calibrate before showing extrinsic results. Maybe need to load Calib_Results.mat file.\n'); + return; +end; + +%if ~exist('no_grid'), + no_grid = 0; +%end; + +if ~exist(['n_sq_x_' num2str(ind_active(1))]), + no_grid = 1; +end; + + +if 0, + +err_std = std(ex'); + +fprintf(1,'\n\nCalibration results without principal point estimation:\n\n'); +fprintf(1,'Focal Length: fc = [ %3.5f %3.5f]\n',fc); +fprintf(1,'Principal point: cc = [ %3.5f %3.5f]\n',cc); +fprintf(1,'Distortion: kc = [ %3.5f %3.5f %3.5f %3.5f]\n',kc); +fprintf(1,'Pixel error: err = [ %3.5f %3.5f]\n\n',err_std); + +end; + + +% Color code for each image: + +colors = 'brgkcm'; + + +%%% Show the extrinsic parameters + +if ~exist('dX'), + eval(['dX = norm(Tc_' num2str(ind_active(1)) ')/10;']); + dY = dX; +end; + +IP = 5*dX*([0 nx-1 nx-1 0 0 ; 0 0 ny-1 ny-1 0;1 1 1 1 1] - [cc;0]*ones(1,5)) ./ ([fc;1]*ones(1,5)); +BASE = 5*dX*([0 1 0 0 0 0;0 0 0 1 0 0;0 0 0 0 0 1]); +IP = reshape([IP;BASE(:,1)*ones(1,5);IP],3,15); + +figure(4); +[a,b] = view; + +figure(4); +plot3(BASE(1,:),BASE(3,:),-BASE(2,:),'b-','linewidth',2'); +hold on; +plot3(IP(1,:),IP(3,:),-IP(2,:),'r-','linewidth',2); +text(6*dX,0,0,'X_c'); +text(-dX,5*dX,0,'Z_c'); +text(0,0,-6*dX,'Y_c'); +text(-dX,-dX,dX,'O_c'); + + +for kk = 1:n_ima, + + if active_images(kk); + + eval(['XX_kk = X_' num2str(kk) ';']); + eval(['omc_kk = omc_' num2str(kk) ';']); + eval(['Tc_kk = Tc_' num2str(kk) ';']); + N_kk = size(XX_kk,2); + + if ~exist(['n_sq_x_' num2str(kk)]), + no_grid = 1; + end; + + if ~no_grid, + eval(['n_sq_x = n_sq_x_' num2str(kk) ';']); + eval(['n_sq_y = n_sq_y_' num2str(kk) ';']); + if (N_kk ~= ((n_sq_x+1)*(n_sq_y+1))), + no_grid = 1; + end; + end; + + if ~isnan(omc_kk(1,1)), + + R_kk = rodrigues(omc_kk); + + YY_kk = R_kk * XX_kk + Tc_kk * ones(1,length(XX_kk)); + + uu = [-dX;-dY;0]/2; + uu = R_kk * uu + Tc_kk; + + if ~no_grid, + YYx = zeros(n_sq_x+1,n_sq_y+1); + YYy = zeros(n_sq_x+1,n_sq_y+1); + YYz = zeros(n_sq_x+1,n_sq_y+1); + + YYx(:) = YY_kk(1,:); + YYy(:) = YY_kk(2,:); + YYz(:) = YY_kk(3,:); + + %keyboard; + + figure(4); + hhh= mesh(YYx,YYz,-YYy); + set(hhh,'edgecolor',colors(rem(kk-1,6)+1),'linewidth',1); %,'facecolor','none'); + %plot3(YY_kk(1,:),YY_kk(3,:),-YY_kk(2,:),['o' colors(rem(kk-1,6)+1)]); + text(uu(1),uu(3),-uu(2),num2str(kk),'fontsize',14,'color',colors(rem(kk-1,6)+1)); + else + + figure(4); + plot3(YY_kk(1,:),YY_kk(3,:),-YY_kk(2,:),['.' colors(rem(kk-1,6)+1)]); + text(uu(1),uu(3),-uu(2),num2str(kk),'fontsize',14,'color',colors(rem(kk-1,6)+1)); + + end; + + end; + + end; + +end; + +figure(4);rotate3d on; +axis('equal'); +title('Extrinsic parameters'); +%view(60,30); +view(a,b); +hold off; + +set(4,'Name','3D','NumberTitle','off'); + diff --git a/SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/extract_grid.m b/SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/extract_grid.m new file mode 100755 index 0000000..1e3cbdb --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/extract_grid.m @@ -0,0 +1,227 @@ +function [x,X,n_sq_x,n_sq_y,ind_orig,ind_x,ind_y] = extract_grid(I,wintx,winty,fc,cc,kc); + +map = gray(256); + + figure(2); + image(I); + colormap(map); + + + if nargin < 2, + + disp('Window size for corner finder (wintx and winty):'); + wintx = input('wintx ([] = 5) = '); + if isempty(wintx), wintx = 5; end; + wintx = round(wintx); + winty = input('winty ([] = 5) = '); + if isempty(winty), winty = 5; end; + winty = round(winty); + + fprintf(1,'Window size = %dx%d\n',2*wintx+1,2*winty+1); + + end; + + + + title('Click on the four extreme corners of the rectangular pattern...'); + + disp('Click on the four extreme corners of the rectangular complete pattern...'); + + [x,y] = ginput3(4); + + [Xc,good,bad,type] = cornerfinder([x';y'],I,winty,wintx); % the four corners + + x = Xc(1,:)'; + y = Xc(2,:)'; + + [y,indy] = sort(y); + x = x(indy); + + if (x(2) > x(1)), + x4 = x(1);y4 = y(1); x3 = x(2); y3 = y(2); + else + x4 = x(2);y4 = y(2); x3 = x(1); y3 = y(1); + end; + if (x(3) > x(4)), + x2 = x(3);y2 = y(3); x1 = x(4); y1 = y(4); + else + x2 = x(4);y2 = y(4); x1 = x(3); y1 = y(3); + end; + + x = [x1;x2;x3;x4]; + y = [y1;y2;y3;y4]; + + + figure(2); hold on; + plot([x;x(1)],[y;y(1)],'g-'); + plot(x,y,'og'); + hx=text((x(4)+x(3))/2,(y(4)+y(3))/2 - 20,'X'); + set(hx,'color','g','Fontsize',14); + hy=text((x(4)+x(1))/2-20,(y(4)+y(1))/2,'Y'); + set(hy,'color','g','Fontsize',14); + hold off; + + + % Try to automatically count the number of squares in the grid + + n_sq_x1 = count_squares(I,x1,y1,x2,y2,wintx); + n_sq_x2 = count_squares(I,x3,y3,x4,y4,wintx); + n_sq_y1 = count_squares(I,x2,y2,x3,y3,wintx); + n_sq_y2 = count_squares(I,x4,y4,x1,y1,wintx); + + + + % If could not count the number of squares, enter manually + + if (n_sq_x1~=n_sq_x2)|(n_sq_y1~=n_sq_y2), + + + disp('Could not count the number of squares in the grid. Enter manually.'); + n_sq_x = input('Number of squares along the X direction ([]=10) = '); %6 + if isempty(n_sq_x), n_sq_x = 10; end; + n_sq_y = input('Number of squares along the Y direction ([]=10) = '); %6 + if isempty(n_sq_y), n_sq_y = 10; end; + + else + + n_sq_x = n_sq_x1; + n_sq_y = n_sq_y1; + + end; + + + % Enter the size of each square + + dX = input(['Size dX of each square along the X direction ([]=3cm) = ']); + dY = input(['Size dY of each square along the Y direction ([]=3cm) = ']); + if isempty(dX), dX = 3; end; + if isempty(dY), dY = 3; end; + + + + % Compute the inside points through computation of the planar homography (collineation) + + a00 = [x(1);y(1);1]; + a10 = [x(2);y(2);1]; + a11 = [x(3);y(3);1]; + a01 = [x(4);y(4);1]; + + + % Compute the planart collineation: (return the normalization matrice as well) + + [Homo,Hnorm,inv_Hnorm] = compute_homography ([a00 a10 a11 a01],[0 1 1 0;0 0 1 1;1 1 1 1]); + + + % Build the grid using the planar collineation: + + x_l = ((0:n_sq_x)'*ones(1,n_sq_y+1))/n_sq_x; + y_l = (ones(n_sq_x+1,1)*(0:n_sq_y))/n_sq_y; + pts = [x_l(:) y_l(:) ones((n_sq_x+1)*(n_sq_y+1),1)]'; + + XX = Homo*pts; + XX = XX(1:2,:) ./ (ones(2,1)*XX(3,:)); + + + % Complete size of the rectangle + + W = n_sq_x*dX; + L = n_sq_y*dY; + + + + if nargin < 6, + + %%%%%%%%%%%%%%%%%%%%%%%% ADDITIONAL STUFF IN THE CASE OF HIGHLY DISTORTED IMAGES %%%%%%%%%%%%% + figure(2); + hold on; + plot(XX(1,:),XX(2,:),'r+'); + title('The red crosses should be close to the image corners'); + hold off; + + disp('If the guessed grid corners (red crosses on the image) are not close to the actual corners,'); + disp('it is necessary to enter an initial guess for the radial distortion factor kc (useful for subpixel detection)'); + quest_distort = input('Need of an initial guess for distortion? ([]=no, other=yes) '); + + quest_distort = ~isempty(quest_distort); + + if quest_distort, + % Estimation of focal length: + c_g = [size(I,2);size(I,1)]/2 + .5; + f_g = Distor2Calib(0,[[x(1) x(2) x(4) x(3)] - c_g(1);[y(1) y(2) y(4) y(3)] - c_g(2)],1,1,4,W,L,[-W/2 W/2 W/2 -W/2;L/2 L/2 -L/2 -L/2; 0 0 0 0],100,1,1); + f_g = mean(f_g); + script_fit_distortion; + end; + %%%%%%%%%%%%%%%%%%%%% END ADDITIONAL STUFF IN THE CASE OF HIGHLY DISTORTED IMAGES %%%%%%%%%%%%% + + else + + xy_corners_undist = comp_distortion_oulu([(x' - cc(1))/fc(1);(y'-cc(2))/fc(1)],kc); + + xu = xy_corners_undist(1,:)'; + yu = xy_corners_undist(2,:)'; + + [XXu] = projectedGrid ( [xu(1);yu(1)], [xu(2);yu(2)],[xu(3);yu(3)], [xu(4);yu(4)],n_sq_x+1,n_sq_y+1); % The full grid + + r2 = sum(XXu.^2); + XX = (ones(2,1)*(1 + kc(1) * r2 + kc(2) * (r2.^2))) .* XXu; + XX(1,:) = fc(1)*XX(1,:)+cc(1); + XX(2,:) = fc(2)*XX(2,:)+cc(2); + + end; + + + Np = (n_sq_x+1)*(n_sq_y+1); + + disp('Corner extraction...'); + + grid_pts = cornerfinder(XX,I,winty,wintx); %%% Finds the exact corners at every points! + + grid_pts = grid_pts - 1; % subtract 1 to bring the origin to (0,0) instead of (1,1) in matlab (not necessary in C) + + ind_corners = [1 n_sq_x+1 (n_sq_x+1)*n_sq_y+1 (n_sq_x+1)*(n_sq_y+1)]; % index of the 4 corners + ind_orig = (n_sq_x+1)*n_sq_y + 1; + xorig = grid_pts(1,ind_orig); + yorig = grid_pts(2,ind_orig); + dxpos = mean([grid_pts(:,ind_orig) grid_pts(:,ind_orig+1)]'); + dypos = mean([grid_pts(:,ind_orig) grid_pts(:,ind_orig-n_sq_x-1)]'); + + + ind_x = (n_sq_x+1)*(n_sq_y + 1); + ind_y = 1; + + x_box_kk = [grid_pts(1,:)-(wintx+.5);grid_pts(1,:)+(wintx+.5);grid_pts(1,:)+(wintx+.5);grid_pts(1,:)-(wintx+.5);grid_pts(1,:)-(wintx+.5)]; + y_box_kk = [grid_pts(2,:)-(winty+.5);grid_pts(2,:)-(winty+.5);grid_pts(2,:)+(winty+.5);grid_pts(2,:)+(winty+.5);grid_pts(2,:)-(winty+.5)]; + + + figure(3); + image(I); colormap(map); hold on; + plot(grid_pts(1,:)+1,grid_pts(2,:)+1,'r+'); + plot(x_box_kk+1,y_box_kk+1,'-b'); + plot(grid_pts(1,ind_corners)+1,grid_pts(2,ind_corners)+1,'mo'); + plot(xorig+1,yorig+1,'*m'); + h = text(xorig-15,yorig-15,'O'); + set(h,'Color','m','FontSize',14); + h2 = text(dxpos(1)-10,dxpos(2)-10,'dX'); + set(h2,'Color','g','FontSize',14); + h3 = text(dypos(1)-25,dypos(2)-3,'dY'); + set(h3,'Color','g','FontSize',14); + xlabel('Xc (in camera frame)'); + ylabel('Yc (in camera frame)'); + title('Extracted corners'); + zoom on; + drawnow; + hold off; + + + Xi = reshape(([0:n_sq_x]*dX)'*ones(1,n_sq_y+1),Np,1)'; + Yi = reshape(ones(n_sq_x+1,1)*[n_sq_y:-1:0]*dY,Np,1)'; + Zi = zeros(1,Np); + + Xgrid = [Xi;Yi;Zi]; + + + % All the point coordinates (on the image, and in 3D) - for global optimization: + + x = grid_pts; + X = Xgrid; + diff --git a/SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/extract_parameters.m b/SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/extract_parameters.m new file mode 100755 index 0000000..8e0e1f1 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/extract_parameters.m @@ -0,0 +1,46 @@ + +%%% Extraction of the final intrinsic and extrinsic paramaters: + +check_active_images; + +fc = solution(1:2); +kc = solution(3:6); +cc = solution(6*n_ima + 4 +3:6*n_ima + 5 +3); + +% Calibration matrix: + +KK = [fc(1) 0 cc(1);0 fc(2) cc(2); 0 0 1]; +inv_KK = inv(KK); + +% Extract the extrinsic paramters, and recomputer the collineations + +for kk = 1:n_ima, + + if active_images(kk), + + omckk = solution(4+6*(kk-1) + 3:6*kk + 3); + Tckk = solution(6*kk+1 + 3:6*kk+3 + 3); + + Rckk = rodrigues(omckk); + + Hkk = KK * [Rckk(:,1) Rckk(:,2) Tckk]; + + Hkk = Hkk / Hkk(3,3); + + else + + omckk = NaN*ones(3,1); + Tckk = NaN*ones(3,1); + Rckk = NaN*ones(3,3); + Hkk = NaN*ones(3,3); + + end; + + eval(['omc_' num2str(kk) ' = omckk;']); + eval(['Rc_' num2str(kk) ' = Rckk;']); + eval(['Tc_' num2str(kk) ' = Tckk;']); + eval(['H_' num2str(kk) '= Hkk;']); + +end; + + diff --git a/SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/extract_parameters3D.m b/SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/extract_parameters3D.m new file mode 100755 index 0000000..841c6ab --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/extract_parameters3D.m @@ -0,0 +1,36 @@ + +%%% Extraction of the final intrinsic and extrinsic paramaters: + + +fc = solution(1:2); +kc = solution(3:6); +cc = solution(6*n_ima + 4 +3:6*n_ima + 5 +3); + +% Calibration matrix: + +KK = [fc(1) 0 cc(1);0 fc(2) cc(2); 0 0 1]; +inv_KK = inv(KK); + +% Extract the extrinsic paramters, and recomputer the collineations + +for kk = 1:n_ima, + + omckk = solution(4+6*(kk-1) + 3:6*kk + 3); + + Tckk = solution(6*kk+1 + 3:6*kk+3 + 3); + + Rckk = rodrigues(omckk); + + Hlkk = KK * [Rckk(:,1) Rckk(:,2) Tckk]; + + Hlkk = Hlkk / Hlkk(3,3); + + eval(['omc_' num2str(kk) ' = omckk;']); + eval(['Rc_' num2str(kk) ' = Rckk;']); + eval(['Tc_' num2str(kk) ' = Tckk;']); + + eval(['Hl_' num2str(kk) '=Hlkk;']); + +end; + + diff --git a/SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/extrinsic_computation.m b/SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/extrinsic_computation.m new file mode 100755 index 0000000..8cf10db --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/extrinsic_computation.m @@ -0,0 +1,173 @@ +%%% INPUT THE IMAGE FILE NAME: + +dir; + +fprintf(1,'\n'); +disp('Computation of the extrinsic parameters from an image of a pattern'); +disp('The intrinsic camera parameters are assumed to be known (previously computed)'); + +fprintf(1,'\n'); +image_name = input('Image name (full name without extension): ','s'); + +format_image2 = '0'; + +while format_image2 == '0', + + format_image2 = input('Image format: ([]=''r''=''ras'', ''b''=''bmp'', ''t''=''tif'', ''p''=''pgm'', ''j''=''jpg'') ','s'); + + if isempty(format_image2), + format_image2 = 'ras'; + end; + + if lower(format_image2(1)) == 'b', + format_image2 = 'bmp'; + else + if lower(format_image2(1)) == 't', + format_image2 = 'tif'; + else + if lower(format_image2(1)) == 'p', + format_image2 = 'pgm'; + else + if lower(format_image2(1)) == 'j', + format_image2 = 'jpg'; + else + if lower(format_image2(1)) == 'r', + format_image2 = 'ras'; + else + disp('Invalid image format'); + format_image2 = '0'; % Ask for format once again + end; + end; + end; + end; + end; +end; + +ima_name = [image_name '.' format_image]; + + + +%%% READ IN IMAGE: + +if format_image(1) == 'p', + I = double(pgmread(ima_name)); +else + if format_image(1) == 'r', + I = readras(ima_name); + else + I = double(imread(ima_name)); + end; +end; + +if size(I,3)>1, + I = I(:,:,2); +end; + + +%%% EXTRACT GRID CORNERS: + +fprintf(1,'\nExtraction of the grid corners on the image\n'); + +disp('Window size for corner finder (wintx and winty):'); +wintx = input('wintx ([] = 5) = '); +if isempty(wintx), wintx = 5; end; +wintx = round(wintx); +winty = input('winty ([] = 5) = '); +if isempty(winty), winty = 5; end; +winty = round(winty); + +fprintf(1,'Window size = %dx%d\n',2*wintx+1,2*winty+1); + +[x_ext,X_ext,n_sq_x,n_sq_y,ind_orig,ind_x,ind_y] = extract_grid(I,wintx,winty,fc,cc,kc); + + + +%%% Computation of the Extrinsic Parameters attached to the grid: + +[omc_ext,Tc_ext,Rc_ext,H_ext] = compute_extrinsic(x_ext,X_ext,fc,cc,kc); + + +%%% Reproject the points on the image: + +[x_reproj] = project_points(X_ext,omc_ext,Tc_ext,fc,cc,kc); + +err_reproj = x_ext - x_reproj; + +err_std2 = std(err_reproj')'; + + +Basis = [X_ext(:,[ind_orig ind_x ind_orig ind_y ind_orig ])]; + +VX = Basis(:,2) - Basis(:,1); +VY = Basis(:,4) - Basis(:,1); + +nX = norm(VX); +nY = norm(VY); + +VZ = min(nX,nY) * cross(VX/nX,VY/nY); + +Basis = [Basis VZ]; + +[x_basis] = project_points(Basis,omc_ext,Tc_ext,fc,cc,kc); + +dxpos = (x_basis(:,2) + x_basis(:,1))/2; +dypos = (x_basis(:,4) + x_basis(:,3))/2; +dzpos = (x_basis(:,6) + x_basis(:,5))/2; + + + +figure(2); +image(I); +colormap(gray(256)); +hold on; +plot(x_ext(1,:)+1,x_ext(2,:)+1,'r+'); +plot(x_reproj(1,:)+1,x_reproj(2,:)+1,'yo'); +h = text(x_ext(1,ind_orig)-25,x_ext(2,ind_orig)-25,'O'); +set(h,'Color','g','FontSize',14); +h2 = text(dxpos(1)+1,dxpos(2)-30,'X'); +set(h2,'Color','g','FontSize',14); +h3 = text(dypos(1)-30,dypos(2)+1,'Y'); +set(h3,'Color','g','FontSize',14); +h4 = text(dzpos(1)-10,dzpos(2)-20,'Z'); +set(h4,'Color','g','FontSize',14); +plot(x_basis(1,:)+1,x_basis(2,:)+1,'g-','linewidth',2); +title('Image points (+) and reprojected grid points (o)'); +hold off; + + +fprintf(1,'\n\nExtrinsic parameters:\n\n'); +fprintf(1,'Translation vector: Tc_ext = [ %3.6f \t %3.6f \t %3.6f ]\n',Tc_ext); +fprintf(1,'Rotation vector: omc_ext = [ %3.6f \t %3.6f \t %3.6f ]\n',omc_ext); +fprintf(1,'Rotation matrix: Rc_ext = [ %3.6f \t %3.6f \t %3.6f\n',Rc_ext(1,:)'); +fprintf(1,' %3.6f \t %3.6f \t %3.6f\n',Rc_ext(2,:)'); +fprintf(1,' %3.6f \t %3.6f \t %3.6f ]\n',Rc_ext(3,:)'); +fprintf(1,'Pixel error: err = [ %3.5f \t %3.5f ]\n\n',err_std2); + + + + + +return; + + +% Stores the results: + +kk = 1; + +% Stores location of grid wrt camera: + +eval(['omc_' num2str(kk) ' = omc_ext;']); +eval(['Tc_' num2str(kk) ' = Tc_ext;']); + +% Stores the projected points: + +eval(['y_' num2str(kk) ' = x_reproj;']); +eval(['X_' num2str(kk) ' = X_ext;']); +eval(['x_' num2str(kk) ' = x_ext;']); + + +% Organize the points in a grid: + +eval(['n_sq_x_' num2str(kk) ' = n_sq_x;']); +eval(['n_sq_y_' num2str(kk) ' = n_sq_y;']); + \ No newline at end of file diff --git a/SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/ginput3.m b/SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/ginput3.m new file mode 100755 index 0000000..56fe496 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/ginput3.m @@ -0,0 +1,216 @@ +function [out1,out2,out3] = ginput2(arg1) +%GINPUT Graphical input from mouse. +% [X,Y] = GINPUT(N) gets N points from the current axes and returns +% the X- and Y-coordinates in length N vectors X and Y. The cursor +% can be positioned using a mouse (or by using the Arrow Keys on some +% systems). Data points are entered by pressing a mouse button +% or any key on the keyboard except carriage return, which terminates +% the input before N points are entered. +% +% [X,Y] = GINPUT gathers an unlimited number of points until the +% return key is pressed. +% +% [X,Y,BUTTON] = GINPUT(N) returns a third result, BUTTON, that +% contains a vector of integers specifying which mouse button was +% used (1,2,3 from left) or ASCII numbers if a key on the keyboard +% was used. + +% Copyright (c) 1984-96 by The MathWorks, Inc. +% $Revision: 5.18 $ $Date: 1996/11/10 17:48:08 $ + +% Fixed version by Jean-Yves Bouguet to have a cross instead of 2 lines +% More visible for images + +P = NaN*ones(16,16); +P(1:15,1:15) = 2*ones(15,15); +P(2:14,2:14) = ones(13,13); +P(3:13,3:13) = NaN*ones(11,11); +P(6:10,6:10) = 2*ones(5,5); +P(7:9,7:9) = 1*ones(3,3); + +out1 = []; out2 = []; out3 = []; y = []; +c = computer; +if ~strcmp(c(1:2),'PC') & ~strcmp(c(1:2),'MA') + tp = get(0,'TerminalProtocol'); +else + tp = 'micro'; +end + +if ~strcmp(tp,'none') & ~strcmp(tp,'x') & ~strcmp(tp,'micro'), + if nargout == 1, + if nargin == 1, + eval('out1 = trmginput(arg1);'); + else + eval('out1 = trmginput;'); + end + elseif nargout == 2 | nargout == 0, + if nargin == 1, + eval('[out1,out2] = trmginput(arg1);'); + else + eval('[out1,out2] = trmginput;'); + end + if nargout == 0 + out1 = [ out1 out2 ]; + end + elseif nargout == 3, + if nargin == 1, + eval('[out1,out2,out3] = trmginput(arg1);'); + else + eval('[out1,out2,out3] = trmginput;'); + end + end +else + + fig = gcf; + figure(gcf); + + if nargin == 0 + how_many = -1; + b = []; + else + how_many = arg1; + b = []; + if isstr(how_many) ... + | size(how_many,1) ~= 1 | size(how_many,2) ~= 1 ... + | ~(fix(how_many) == how_many) ... + | how_many < 0 + error('Requires a positive integer.') + end + if how_many == 0 + ptr_fig = 0; + while(ptr_fig ~= fig) + ptr_fig = get(0,'PointerWindow'); + end + scrn_pt = get(0,'PointerLocation'); + loc = get(fig,'Position'); + pt = [scrn_pt(1) - loc(1), scrn_pt(2) - loc(2)]; + out1 = pt(1); y = pt(2); + elseif how_many < 0 + error('Argument must be a positive integer.') + end + end + +pointer = get(gcf,'pointer'); + +set(gcf,'Pointer','custom','PointerShapeCData',P,'PointerShapeHotSpot',[8,8]); +%set(gcf,'pointer','crosshair'); + fig_units = get(fig,'units'); + char = 0; + + while how_many ~= 0 + % Use no-side effect WAITFORBUTTONPRESS + waserr = 0; + eval('keydown = wfbp;', 'waserr = 1;'); + if(waserr == 1) + if(ishandle(fig)) + set(fig,'pointer',pointer,'units',fig_units); + error('Interrupted'); + else + error('Interrupted by figure deletion'); + end + end + + ptr_fig = get(0,'CurrentFigure'); + if(ptr_fig == fig) + if keydown + char = get(fig, 'CurrentCharacter'); + button = abs(get(fig, 'CurrentCharacter')); + scrn_pt = get(0, 'PointerLocation'); + set(fig,'units','pixels') + loc = get(fig, 'Position'); + pt = [scrn_pt(1) - loc(1), scrn_pt(2) - loc(2)]; + set(fig,'CurrentPoint',pt); + else + button = get(fig, 'SelectionType'); + if strcmp(button,'open') + button = b(length(b)); + elseif strcmp(button,'normal') + button = 1; + elseif strcmp(button,'extend') + button = 2; + elseif strcmp(button,'alt') + button = 3; + else + error('Invalid mouse selection.') + end + end + pt = get(gca, 'CurrentPoint'); + + how_many = how_many - 1; + + if(char == 13) % & how_many ~= 0) + % if the return key was pressed, char will == 13, + % and that's our signal to break out of here whether + % or not we have collected all the requested data + % points. + % If this was an early breakout, don't include + % the key info in the return arrays. + % We will no longer count it if it's the last input. + break; + end + + out1 = [out1;pt(1,1)]; + y = [y;pt(1,2)]; + b = [b;button]; + end + end + + set(fig,'pointer',pointer,'units',fig_units); + + if nargout > 1 + out2 = y; + if nargout > 2 + out3 = b; + end + else + out1 = [out1 y]; + end + +end + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +function key = wfbp +%WFBP Replacement for WAITFORBUTTONPRESS that has no side effects. + +% Remove figure button functions +fprops = {'windowbuttonupfcn','buttondownfcn', ... + 'windowbuttondownfcn','windowbuttonmotionfcn'}; +fig = gcf; +fvals = get(fig,fprops); +set(fig,fprops,{'','','',''}) + +% Remove all other buttondown functions +ax = findobj(fig,'type','axes'); +if isempty(ax) + ch = {}; +else + ch = get(ax,{'Children'}); +end +for i=1:length(ch), + ch{i} = ch{i}(:)'; +end +h = [ax(:)',ch{:}]; +vals = get(h,{'buttondownfcn'}); +mt = repmat({''},size(vals)); +set(h,{'buttondownfcn'},mt); + +% Now wait for that buttonpress, and check for error conditions +waserr = 0; +eval(['if nargout==0,', ... + ' waitforbuttonpress,', ... + 'else,', ... + ' keydown = waitforbuttonpress;',... + 'end' ], 'waserr = 1;'); + +% Put everything back +if(ishandle(fig)) + set(fig,fprops,fvals) + set(h,{'buttondownfcn'},vals) +end + +if(waserr == 1) + error('Interrupted'); +end + +if nargout>0, key = keydown; end +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% diff --git a/SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/go_calib_optim.m b/SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/go_calib_optim.m new file mode 100755 index 0000000..6eb1c82 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/go_calib_optim.m @@ -0,0 +1,60 @@ +%go_calib_optim +% +%Main calibration function. Computes the intrinsic andextrinsic parameters. +%Runs as a script. +% +%INPUT: x_1,x_2,x_3,...: Feature locations on the images +% X_1,X_2,X_3,...: Corresponding grid coordinates +% +%OUTPUT: fc: Camera focal length +% cc: Principal point coordinates +% kc: Distortion coefficients +% KK: The camera matrix (containing fc and cc) +% omc_1,omc_2,omc_3,...: 3D rotation vectors attached to the grid positions in space +% Tc_1,Tc_2,Tc_3,...: 3D translation vectors attached to the grid positions in space +% Rc_1,Rc_2,Rc_3,...: 3D rotation matrices corresponding to the omc vectors +% +%Method: Minimizes the pixel reprojection error in the least squares sense over the intrinsic +% camera parameters, and the extrinsic parameters (3D locations of the grids in space) +% +%Note: If the intrinsic camera parameters (fc, cc, kc) do not exist before, they are initialized through +% the function init_intrinsic_param.m. Otherwise, the variables in memory are used as initial guesses. +% +%Note: The row vector active_images consists of zeros and ones. To deactivate an image, set the +% corresponding entry in the active_images vector to zero. +% +%VERY IMPORTANT: This function works for 2D and 3D calibration rigs, except for init_intrinsic_param.m +%that is so far implemented to work only with 2D rigs. +%In the future, a more general function will be there. +%For now, if using a 3D calibration rig, set quick_init to 1 for an easy initialization of the focal length + + +desactivated_images = []; + + +go_calib_optim_iter; + + +if ~isempty(desactivated_images), + + param_list_save = param_list; + + fprintf(1,'\nNew optimization including the images that have been deactivated during the previous optimization.\n'); + active_images(desactivated_images) = ones(1,length(desactivated_images)); + desactivated_images = []; + + go_calib_optim_iter; + + if ~isempty(desactivated_images), + fprintf(1,['List of images left desactivated: ' num2str(desactivated_images) '\n' ] ); + end; + + param_list = [param_list_save(:,1:end-1) param_list]; + +end; + + +%%%%%%%%%%%%%%%%%%%% GRAPHICAL OUTPUT %%%%%%%%%%%%%%%%%%%%%%%% + +%graphout_calib; + diff --git a/SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/go_calib_optim3D.m b/SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/go_calib_optim3D.m new file mode 100755 index 0000000..8cc5e30 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/go_calib_optim3D.m @@ -0,0 +1,264 @@ +% Simplified version of go_calib.m + + +if ~exist('x_1'), + click_calib; +end; + + +fprintf(1,'\nMain calibration procedure\n'); + +% initial guess for principal point and distortion: +c_init = [nx;ny]/2 - 0.5; % initialize at the center of the image +k_init = [0;0;0;0]; % initialize to zero (no distortion) + + +% Compute explicitely the focal lentgh using all the (mutually orthogonal) vanishing points +% note: The vanihing points are hidden in the planar collineations H_kk + +A = []; +b = []; + +% matrix that subtract the principal point: +Sub_cc = [1 0 -c_init(1);0 1 -c_init(2);0 0 1]; + + +for kk=1:n_ima, + + % left Pattern: + + eval(['Hlkk = Hl_' num2str(kk) ';']); + + Hlkk = Sub_cc * Hlkk; + + % Extract vanishing points (direct and diagonals): + + Vl_hori_pix = Hlkk(:,1); + Vl_vert_pix = Hlkk(:,2); + Vl_diag1_pix = (Hlkk(:,1)+Hlkk(:,2))/2; + Vl_diag2_pix = (Hlkk(:,1)-Hlkk(:,2))/2; + + Vl_hori_pix = Vl_hori_pix/norm(Vl_hori_pix); + Vl_vert_pix = Vl_vert_pix/norm(Vl_vert_pix); + Vl_diag1_pix = Vl_diag1_pix/norm(Vl_diag1_pix); + Vl_diag2_pix = Vl_diag2_pix/norm(Vl_diag2_pix); + + al1 = Vl_hori_pix(1); + bl1 = Vl_hori_pix(2); + cl1 = Vl_hori_pix(3); + + al2 = Vl_vert_pix(1); + bl2 = Vl_vert_pix(2); + cl2 = Vl_vert_pix(3); + + al3 = Vl_diag1_pix(1); + bl3 = Vl_diag1_pix(2); + cl3 = Vl_diag1_pix(3); + + al4 = Vl_diag2_pix(1); + bl4 = Vl_diag2_pix(2); + cl4 = Vl_diag2_pix(3); + + % right Pattern: + + eval(['Hrkk = Hr_' num2str(kk) ';']); + + Hrkk = Sub_cc * Hrkk; + + % Extract vanishing points (direct and diagonals): + + Vr_hori_pix = Hrkk(:,1); + Vr_vert_pix = Hrkk(:,2); + Vr_diag1_pix = (Hrkk(:,1)+Hrkk(:,2))/2; + Vr_diag2_pix = (Hrkk(:,1)-Hrkk(:,2))/2; + + Vr_hori_pix = Vr_hori_pix/norm(Vl_hori_pix); + Vr_vert_pix = Vr_vert_pix/norm(Vl_vert_pix); + Vr_diag1_pix = Vr_diag1_pix/norm(Vr_diag1_pix); + Vr_diag2_pix = Vr_diag2_pix/norm(Vr_diag2_pix); + + ar1 = Vr_hori_pix(1); + br1 = Vr_hori_pix(2); + cr1 = Vr_hori_pix(3); + + ar2 = Vr_vert_pix(1); + br2 = Vr_vert_pix(2); + cr2 = Vr_vert_pix(3); + + ar3 = Vr_diag1_pix(1); + br3 = Vr_diag1_pix(2); + cr3 = Vr_diag1_pix(3); + + ar4 = Vr_diag2_pix(1); + br4 = Vr_diag2_pix(2); + cr4 = Vr_diag2_pix(3); + + + % Collect all the constraints: + + A_kk = [al1*al2 bl1*bl2; + al3*al4 bl3*bl4; + ar1*ar2 br1*br2; + ar3*ar4 br3*br4; + al1*ar1 bl1*br1]; + + b_kk = -[cl1*cl2;cl3*cl4;cr1*cr2;cr3*cr4;cl1*cr1]; + + + A = [A;A_kk]; + b = [b;b_kk]; + +end; + +% use all the vanishing points to estimate focal length: + +f_init = sqrt(abs(1./(inv(A'*A)*A'*b))); % if using a two-focal model for initial guess + +%f_init = sqrt(b'*(sum(A')') / (b'*b)) * ones(2,1); % if single focal length model is used + + +% Global calibration matrix (initial guess): + +KK = [f_init(1) 0 c_init(1);0 f_init(2) c_init(2); 0 0 1]; +inv_KK = inv(KK); + + +% Computing of the extrinsic parameters (from the collineations) + +for kk = 1:n_ima, + + eval(['Hlkk = Hl_' num2str(kk) ';']); + + Hl2 = inv_KK*Hlkk; + + sc = mean([norm(Hl2(:,1));norm(Hl2(:,2))]); + + Hl2 = Hl2/sc; + + eval(['Hrkk = Hr_' num2str(kk) ';']); + + Hr2 = inv_KK*Hrkk; + + sc = mean([norm(Hr2(:,1));norm(Hr2(:,2))]); + + Hr2 = Hr2/sc; + + omcl = rodrigues([Hl2(:,1:2) cross(Hl2(:,1),Hl2(:,2))]); + Tcl = Hl2(:,3); + + %omcr = rodrigues([Hr2(:,1:2) cross(Hr2(:,1),Hr2(:,2))]); + %Tcr = Hr2(:,3); + + + omckk = omcl; %rodrigues([H2(:,1:2) cross(H2(:,1),H2(:,2))]); + Tckk = Tcl; %H2(:,3); + + eval(['omc_' num2str(kk) ' = omckk;']); + eval(['Tc_' num2str(kk) ' = Tckk;']); + +end; + + + +% Initialisation of the parameters for global minimization: + +init_param = [f_init;k_init]; + +for kk = 1:n_ima, + eval(['init_param = [init_param; omc_' num2str(kk) '; Tc_' num2str(kk) '];']); +end; + +if ~exist('lsqnonlin'), + + options = [1 1e-4 1e-4 1e-6 0 0 0 0 0 0 0 0 0 6000 0 1e-8 0.1 0]; + + if exist('leastsq'), + sss = ['[param,opt] = leastsq(''multi_error_oulu'',init_param,options,[],n_ima,c_init);']; + else + sss = ['[param,opt] = leastsq2(''multi_error_oulu'',init_param,options,[],n_ima,c_init);']; + end; + +else + + options = optimset('lsqnonlin'); + options.MaxIter = 6000; + options.Display = 'iter'; + sss = ['[param,opt] = lsqnonlin(''multi_error_oulu'',init_param,[],[],options,n_ima,c_init);']; + +end; + + +fprintf(1,'\nOptimization not including the principal point...\n') +eval(sss); + +history = [[init_param;c_init] [param;c_init]]; + +sol_no_center = [param;c_init]; + +init_param = sol_no_center; + +fprintf(1,'\nOptimization including the principal point...\n') + +eval(sss); + +history = [history param]; + + +sol_with_center = param; + + + + +%%% Extraction of the final intrinsic and extrinsic paramaters (in the no-center case): + +solution = sol_no_center; +extract_parameters3D; + +fprintf(1,'\n\nCalibration results without principal point estimation:\n\n'); +fprintf(1,'Focal Length: fc = [ %3.5f %3.5f]\n',fc); +fprintf(1,'Principal point: cc = [ %3.5f %3.5f]\n',cc); +fprintf(1,'Distortion: kc = [ %3.5f %3.5f %3.5f %3.5f]\n',kc); +fprintf(1,['Pixel error: [click on ''sol. without center'']\n']); + + + + +% Pick the solution with principal point +%%% NOTE: At that point, the user can choose which solution to pick: with or without +%%% principal point estimation. By default, we pick the solution with principal point. + +solution = sol_with_center; + + + +%%% Extraction of the final intrinsic and extrinsic paramaters: + +extract_parameters3D; + + +fprintf(1,'\n\nCalibration results with principal point estimation:\n\n'); +fprintf(1,'Focal Length: fc = [ %3.5f %3.5f]\n',fc); +fprintf(1,'Principal point: cc = [ %3.5f %3.5f]\n',cc); +fprintf(1,'Distortion: kc = [ %3.5f %3.5f %3.5f %3.5f]\n',kc); + + +%%%%%%%%%%%%%%%%%%%% GRAPHICAL OUTPUT %%%%%%%%%%%%%%%%%%%%%%%% + +graphout_calib3D; + + + +fprintf(1,'Note: If the solution is not satisfactory, select solution without center estimation.\n\n'); + + +%%%%%%%%%%%%%% Save all the Calibration results: + +disp('Save calibration results under Calib_Results.mat'); + +string_save = 'save Calib_Results fc kc cc ex x y solution sol_with_center sol_no_center history wintx winty n_ima type_numbering N_slots small_calib_image first_num image_numbers format_image calib_name Hcal Wcal nx ny map dX_default dY_default KK inv_KK dX dY'; + +for kk = 1:n_ima, + string_save = [string_save ' X_' num2str(kk) ' x_' num2str(kk) ' y_' num2str(kk) ' ex_' num2str(kk) ' omc_' num2str(kk) ' Tc_' num2str(kk) ' Hl_' num2str(kk) ' nl_sq_x_' num2str(kk) ' nl_sq_y_' num2str(kk) ' Hr_' num2str(kk) ' nr_sq_x_' num2str(kk) ' nr_sq_y_' num2str(kk)]; +end; + +eval(string_save); diff --git a/SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/go_calib_optim_cont.m b/SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/go_calib_optim_cont.m new file mode 100755 index 0000000..9ff3f0b --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/go_calib_optim_cont.m @@ -0,0 +1,142 @@ +% Simplified version of go_calib.m + +if ~exist('x_1'), + click_calib; +end; + + +% Initialisation of the parameters for global minimization: + +init_param = [fc;kc]; + +for kk = 1:n_ima, + + if ~exist(['omc_' num2str(kk)]), + eval(['Hkk = H_' num2str(kk) ';']); + H2 = inv_KK*Hkk; + sc = mean([norm(H2(:,1));norm(H2(:,2))]); + H2 = H2/sc; + omckk = rodrigues([H2(:,1:2) cross(H2(:,1),H2(:,2))]); + Tckk = H2(:,3); + eval(['omc_' num2str(kk) ' = omckk;']); + eval(['Tc_' num2str(kk) ' = Tckk;']); + end; + + eval(['init_param = [init_param; omc_' num2str(kk) '; Tc_' num2str(kk) '];']); +end; + +init_param = [init_param;cc]; + + + +%-------------------- Main Optimization: + +fprintf(1,'\nRe-Optimization...\n') + + +param = init_param; +change = 1; + +iter = 0; + +fprintf(1,'Iteration '); + +while (change > 1e-6)&(iter < 10), + + fprintf(1,'%d...',iter+1); + + JJ = []; + ex = []; + + c = param(6*n_ima + 4 + 3:6*n_ima + 5 + 3); + f = param(1:2); + k = param(3:6); + + for kk = 1:n_ima, + + omckk = param(4+6*(kk-1) + 3:6*kk + 3); + + Tckk = param(6*kk+1 + 3:6*kk+3 + 3); + + eval(['X_kk = X_' num2str(kk) ';']); + eval(['x_kk = x_' num2str(kk) ';']); + + Np = size(X_kk,2); + + JJkk = zeros(2*Np,n_ima * 6 + 8); + + [x,dxdom,dxdT,dxdf,dxdc,dxdk] = project_points(X_kk,omckk,Tckk,f,c,k); + + exkk = x_kk - x; + + ex = [ex;exkk(:)]; + + JJkk(:,1:2) = dxdf; + JJkk(:,3:6) = dxdk; + JJkk(:,4+6*(kk-1) + 3:6*kk + 3) = dxdom; + JJkk(:,6*kk+1 + 3:6*kk+3 + 3) = dxdT; + JJkk(:,6*n_ima + 4 + 3:6*n_ima + 5 + 3) = dxdc; + + JJ = [JJ;JJkk]; + + end; + + param_innov = inv(JJ'*JJ)*(JJ')*ex; + param_up = param + param_innov; + change = norm(param_innov)/norm(param_up); + param = param_up; + iter = iter + 1; + +end; + +fprintf(1,'\n'); + + +sol_with_center = param; + +solution = sol_with_center; + + +%%% Extraction of the final intrinsic and extrinsic paramaters: + +extract_parameters; +comp_error_calib; + +fprintf(1,'\n\nCalibration results with principal point estimation:\n\n'); +fprintf(1,'Focal Length: fc = [ %3.5f %3.5f]\n',fc); +fprintf(1,'Principal point: cc = [ %3.5f %3.5f]\n',cc); +fprintf(1,'Distortion: kc = [ %3.5f %3.5f %3.5f %3.5f]\n',kc); +fprintf(1,'Pixel error: err = [ %3.5f %3.5f]\n\n',err_std); + + +%%%%%%%%%%%%%%%%%%%% GRAPHICAL OUTPUT %%%%%%%%%%%%%%%%%%%%%%%% + +graphout_calib; + + + +fprintf(1,'Note: If the solution is not satisfactory, select solution without center estimation.\n\n'); + + +%%%%%%%%%%%%%% Save all the Calibration results: + +disp('Save calibration results under Calib_Results.mat'); + +string_save = 'save Calib_Results fc kc cc ex x y solution sol_with_center solution_init history wintx winty n_ima type_numbering N_slots small_calib_image first_num image_numbers format_image calib_name Hcal Wcal nx ny map dX_default dY_default KK inv_KK dX dY'; + +for kk = 1:n_ima, + string_save = [string_save ' X_' num2str(kk) ' x_' num2str(kk) ' y_' num2str(kk) ' ex_' num2str(kk) ' omc_' num2str(kk) ' Rc_' num2str(kk) ' Tc_' num2str(kk) ' H_' num2str(kk) ' Hini_' num2str(kk) ' n_sq_x_' num2str(kk) ' n_sq_y_' num2str(kk) ' wintx_' num2str(kk) ' winty_' num2str(kk) ' dX_' num2str(kk) ' dY_' num2str(kk)]; +end; + +eval(string_save); + +return; + +if exist('calib_data.mat'), + ccc = computer; + if ccc(1)=='P', + eval('!del calib_data.mat'); + else + eval('!rm calib_data.mat'); + end; +end; diff --git a/SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/go_calib_optim_iter.m b/SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/go_calib_optim_iter.m new file mode 100755 index 0000000..a076214 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/go_calib_optim_iter.m @@ -0,0 +1,332 @@ +%go_calib_optim_iter +% +%Main calibration function. Computes the intrinsic andextrinsic parameters. +%Runs as a script. +% +%INPUT: x_1,x_2,x_3,...: Feature locations on the images +% X_1,X_2,X_3,...: Corresponding grid coordinates +% +%OUTPUT: fc: Camera focal length +% cc: Principal point coordinates +% kc: Distortion coefficients +% KK: The camera matrix (containing fc and cc) +% omc_1,omc_2,omc_3,...: 3D rotation vectors attached to the grid positions in space +% Tc_1,Tc_2,Tc_3,...: 3D translation vectors attached to the grid positions in space +% Rc_1,Rc_2,Rc_3,...: 3D rotation matrices corresponding to the omc vectors +% +%Method: Minimizes the pixel reprojection error in the least squares sense over the intrinsic +% camera parameters, and the extrinsic parameters (3D locations of the grids in space) +% +%Note: If the intrinsic camera parameters (fc, cc, kc) do not exist before, they are initialized through +% the function init_intrinsic_param.m. Otherwise, the variables in memory are used as initial guesses. +% +%Note: The row vector active_images consists of zeros and ones. To deactivate an image, set the +% corresponding entry in the active_images vector to zero. +% +%VERY IMPORTANT: This function works for 2D and 3D calibration rigs, except for init_intrinsic_param.m +%that is so far implemented to work only with 2D rigs. +%In the future, a more general function will be there. +%For now, if using a 3D calibration rig, quick_init is set to 1 for an easy initialization of the focal length + + +check_active_images; + + + +quick_init = 0; % Set to 1 for using a quick init (necessary when using 3D rigs) + + + +% Check 3D-ness of the calibration rig: +rig3D = 0; +for kk = ind_active, + eval(['X_kk = X_' num2str(kk) ';']); + if is3D(X_kk), + rig3D = 1; + end; +end; + + + +% If the rig is 3D, then no choice: the only valid initialization is manual! +if rig3D, + quick_init = 1; +end; + + + + +alpha = 0.4; % set alpha = 1; for steepest gradient descent + + +% Conditioning threshold for view rejection +thresh_cond = 1e6; + + + + +%% Initialization of the intrinsic parameters (if necessary) + +if ~exist('cc'), + fprintf(1,'Initialization of the principal point at the center of the image.\n'); + cc = [(nx-1)/2;(ny-1)/2]; +end; + + +if ~exist('kc'), + fprintf(1,'Initialization of the image distortion to zero.\n'); + kc = zeros(4,1); +end; + + +if ~exist('fc')& quick_init, + FOV_angle = 35; % Initial camera field of view in degrees + fprintf(1,['Initialization of the focal length to a FOV of ' num2str(FOV_angle) ' degrees.\n']); + fc = (nx/2)/tan(pi*FOV_angle/360) * ones(2,1); +end; + + +if ~exist('fc'), + % Initialization of the intrinsic parameters: + fprintf(1,'Initialization of the intrinsic parameters using the vanishing points of planar patterns.\n') + init_intrinsic_param; % The right way to go (if quick_init is not active)! +end; + + + +%% Initialization of the extrinsic parameters for global minimization: + +init_param = [fc;kc]; + +for kk = 1:n_ima, + + if exist(['x_' num2str(kk)]), + + eval(['x_kk = x_' num2str(kk) ';']); + eval(['X_kk = X_' num2str(kk) ';']); + + if (isnan(x_kk(1,1))), + if active_images(kk), + fprintf(1,'Warning: Cannot calibrate with image %d. Need to extract grid corners first.\n',kk) + fprintf(1,' Set active_images(%d)=1; and run Extract grid corners.\n',kk) + end; + active_images(kk) = 0; + end; + if active_images(kk), + [omckk,Tckk] = compute_extrinsic_init(x_kk,X_kk,fc,cc,kc); + [omckk,Tckk,Rckk,JJ_kk] = compute_extrinsic_refine(omckk,Tckk,x_kk,X_kk,fc,cc,kc,20,thresh_cond); + if cond(JJ_kk)> thresh_cond, + active_images(kk) = 0; + omckk = NaN*ones(3,1); + Tckk = NaN*ones(3,1); + fprintf(1,'\nWarning: View #%d ill-conditioned. This image is now set inactive.\n',kk) + desactivated_images = [desactivated_images kk]; + end; + if isnan(omckk(1,1)), + %fprintf(1,'\nWarning: Desactivating image %d. Re-activate it later by typing:\nactive_images(%d)=1;\nand re-run optimization\n',[kk kk]) + active_images(kk) = 0; + end; + else + omckk = NaN*ones(3,1); + Tckk = NaN*ones(3,1); + end; + + else + + omckk = NaN*ones(3,1); + Tckk = NaN*ones(3,1); + + if active_images(kk), + fprintf(1,'Warning: Cannot calibrate with image %d. Need to extract grid corners first.\n',kk) + fprintf(1,' Set active_images(%d)=1; and run Extract grid corners.\n',kk) + end; + + active_images(kk) = 0; + + end; + + eval(['omc_' num2str(kk) ' = omckk;']); + eval(['Tc_' num2str(kk) ' = Tckk;']); + + eval(['init_param = [init_param; omc_' num2str(kk) '; Tc_' num2str(kk) '];']); + +end; + + +check_active_images; + +init_param = [init_param;cc]; + +%-------------------- Main Optimization: + +fprintf(1,'\nMain calibration optimization procedure - Number of images: %d\n',length(ind_active)); + + +% The following vector helps to select the variables to update: +ind_Jac = find([ones(6,1);reshape(ones(6,1)*active_images,6*n_ima,1);ones(2,1)])'; + +param = init_param; +change = 1; + +iter = 0; + +fprintf(1,'Gradient descent iterations: '); + +param_list = param; + +MaxIter = 30; + + +while (change > 1e-6)&(iter < MaxIter), + + fprintf(1,'%d...',iter+1); + + + %% The first step consists of updating the whole vector of knowns (intrinsic + extrinsic of active + %% images) through a one step steepest gradient descent. + + JJ = []; + ex = []; + + c = param(6*n_ima + 4 + 3:6*n_ima + 5 + 3); + f = param(1:2); + k = param(3:6); + + for kk = 1:n_ima, + + if active_images(kk), + + omckk = param(4+6*(kk-1) + 3:6*kk + 3); + + Tckk = param(6*kk+1 + 3:6*kk+3 + 3); + + if isnan(omckk(1)), + fprintf(1,'Intrinsic parameters at frame %d do not exist\n',kk); + return; + end; + + eval(['X_kk = X_' num2str(kk) ';']); + eval(['x_kk = x_' num2str(kk) ';']); + + Np = size(X_kk,2); + + JJkk = zeros(2*Np,n_ima * 6 + 8); + + [x,dxdom,dxdT,dxdf,dxdc,dxdk] = project_points(X_kk,omckk,Tckk,f,c,k); + + exkk = x_kk - x; + + ex = [ex;exkk(:)]; + + JJkk(:,1:2) = dxdf; + JJkk(:,3:6) = dxdk; + JJkk(:,4+6*(kk-1) + 3:6*kk + 3) = dxdom; + JJkk(:,6*kk+1 + 3:6*kk+3 + 3) = dxdT; + JJkk(:,6*n_ima + 4 + 3:6*n_ima + 5 + 3) = dxdc; + + JJ = [JJ;JJkk]; + + + % Check if this view is ill-conditioned: + JJ_kk = [dxdom dxdT]; + if cond(JJ_kk)> thresh_cond, + active_images(kk) = 0; + fprintf(1,'\nWarning: View #%d ill-conditioned. This image is now set inactive.\n',kk) + desactivated_images = [desactivated_images kk]; + param(4+6*(kk-1) + 3:6*kk+3 + 3) = NaN*ones(6,1); + end; + + + end; + + end; + + + % List of active images (necessary if changed): + check_active_images; + ind_Jac = find([ones(6,1);reshape(ones(6,1)*active_images,6*n_ima,1);ones(2,1)])'; + + + JJ = JJ(:,ind_Jac); + + JJ2 = JJ'*JJ; + + + % Smoothing coefficient: + + alpha2 = 1-(1-alpha)^(iter+1); %set to 1 to undo any smoothing! + + + param_innov = alpha2*inv(JJ2)*(JJ')*ex; + param_up = param(ind_Jac) + param_innov; + param(ind_Jac) = param_up; + + + % New intrinsic parameters: + + fc_current = param(1:2); + cc_current = param(6*n_ima + 4 + 3:6*n_ima + 5 + 3); + kc_current = param(3:6); + + + % Change on the intrinsic parameters: + change = norm([fc_current;cc_current] - [f;c])/norm([fc_current;cc_current]); + + + %% Second step: (optional) - It makes convergence faster, and the region of convergence LARGER!!! + %% Recompute the extrinsic parameters only using compute_extrinsic.m (this may be useful sometimes) + %% The complete gradient descent method is useful to precisely update the intrinsic parameters. + + MaxIter2 = 20; + + for kk = 1:n_ima, + if active_images(kk), + omc_current = param(4+6*(kk-1) + 3:6*kk + 3); + Tc_current = param(6*kk+1 + 3:6*kk+3 + 3); + eval(['X_kk = X_' num2str(kk) ';']); + eval(['x_kk = x_' num2str(kk) ';']); + [omc_current,Tc_current] = compute_extrinsic_init(x_kk,X_kk,fc_current,cc_current,kc_current); + [omckk,Tckk,Rckk,JJ_kk] = compute_extrinsic_refine(omc_current,Tc_current,x_kk,X_kk,fc_current,cc_current,kc_current,MaxIter2,thresh_cond); + if cond(JJ_kk)> thresh_cond, + active_images(kk) = 0; + fprintf(1,'\nWarning: View #%d ill-conditioned. This image is now set inactive.\n',kk) + desactivated_images = [desactivated_images kk]; + omckk = NaN*ones(3,1); + Tckk = NaN*ones(3,1); + end; + param(4+6*(kk-1) + 3:6*kk + 3) = omckk; + param(6*kk+1 + 3:6*kk+3 + 3) = Tckk; + end; + end; + + %fprintf(1,'\n\nCalibration results after optimization:\n\n'); + %fprintf(1,'focal = [%3.5f %3.5f]\n',fc_current); + %fprintf(1,'center = [%3.5f %3.5f]\n',cc_current); + %fprintf(1,'distortion = [%3.5f %3.5f %3.5f %3.5f]\n\n',kc_current); + + + param_list = [param_list param]; + + iter = iter + 1; + +end; + +fprintf(1,'\n'); + + +sol_with_center = param; + +solution = param; + + +%%% Extraction of the final intrinsic and extrinsic paramaters: + +extract_parameters; +comp_error_calib; + +fprintf(1,'\n\nCalibration results after optimization:\n\n'); +fprintf(1,'Focal Length: fc = [ %3.5f %3.5f]\n',fc); +fprintf(1,'Principal point: cc = [ %3.5f %3.5f]\n',cc); +fprintf(1,'Distortion: kc = [ %3.5f %3.5f %3.5f %3.5f]\n',kc); +fprintf(1,'Pixel error: err = [ %3.5f %3.5f]\n\n',err_std); + diff --git a/SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/graphout_calib.m b/SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/graphout_calib.m new file mode 100755 index 0000000..a3f7040 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/graphout_calib.m @@ -0,0 +1,12 @@ + + +%%%%%%%%%%%%%%%%%%%% GRAPHICAL OUTPUT %%%%%%%%%%%%%%%%%%%%%%%% + +%%%%%%%%%%%%%%%%%%%% SHOW EXTRINSIC RESULTS %%%%%%%%%%%%%%%%%%%%%%%% + +ext_calib; + +%%%%%%%%%%%%%%%%%%%% REPROJECT ON THE IMAGES %%%%%%%%%%%%%%%%%%%%%%%% + +reproject_calib; + diff --git a/SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/graphout_calib3D.m b/SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/graphout_calib3D.m new file mode 100755 index 0000000..b7edf43 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/graphout_calib3D.m @@ -0,0 +1,153 @@ + + +%%%%%%%%%%%%%%%%%%%% GRAPHICAL OUTPUT %%%%%%%%%%%%%%%%%%%%%%%% + + +% Color code for each image: + +colors = 'brgkcm'; + + +%%% Show the extrinsic parameters + +IP = 8*dX*([0 nx-1 nx-1 0 0 ; 0 0 ny-1 ny-1 0;1 1 1 1 1] - [cc;0]*ones(1,5)) ./ ([fc;1]*ones(1,5)); + + +figure(4); +[a,b] = view; + +figure(4); +plot3(5*[0 dX 0 0 0 0 ],5*[0 0 0 0 0 dX],-5*[0 0 0 dX 0 0 ],'b-','linewidth',2'); +hold on; +plot3(IP(1,:),IP(3,:),-IP(2,:),'r-','linewidth',2); +text(6*dX,0,0,'X_c'); +text(-dX,5*dX,0,'Z_c'); +text(0,0,-6*dX,'Y_c'); +text(-dX,-dX,dX,'O_c'); + + +for kk = 1:n_ima, + + eval(['XX_kk = X_' num2str(kk) ';']); + eval(['omc_kk = omc_' num2str(kk) ';']); + eval(['Tc_kk = Tc_' num2str(kk) ';']); + + eval(['nl_sq_x = nl_sq_x_' num2str(kk) ';']); + eval(['nl_sq_y = nl_sq_y_' num2str(kk) ';']); + + eval(['nr_sq_x = nr_sq_x_' num2str(kk) ';']); + eval(['nr_sq_y = nr_sq_y_' num2str(kk) ';']); + + R_kk = rodrigues(omc_kk); + + YY_kk = R_kk * XX_kk + Tc_kk * ones(1,length(XX_kk)); + + YYl_kk = YY_kk(:,1:(nl_sq_x+1)*(nl_sq_y+1)); + YYr_kk = YY_kk(:,(nl_sq_x+1)*(nl_sq_y+1)+1:end); + + + eval(['YYl_' num2str(kk) ' = YYl_kk;']); + eval(['YYr_' num2str(kk) ' = YYr_kk;']); + + uu = [-dX;-dY;0]/2; + uu = R_kk * uu + Tc_kk; + + YYlx = zeros(nl_sq_x+1,nl_sq_y+1); + YYly = zeros(nl_sq_x+1,nl_sq_y+1); + YYlz = zeros(nl_sq_x+1,nl_sq_y+1); + + YYrx = zeros(nr_sq_x+1,nr_sq_y+1); + YYry = zeros(nr_sq_x+1,nr_sq_y+1); + YYrz = zeros(nr_sq_x+1,nr_sq_y+1); + + YYlx(:) = YYl_kk(1,:); + YYly(:) = YYl_kk(2,:); + YYlz(:) = YYl_kk(3,:); + + YYrx(:) = YYr_kk(1,:); + YYry(:) = YYr_kk(2,:); + YYrz(:) = YYr_kk(3,:); + + + %keyboard; + + figure(4); + hhh= mesh(YYlx,YYlz,-YYly); + set(hhh,'edgecolor',colors(rem(kk-1,6)+1),'linewidth',1); %,'facecolor','none'); + %plot3(YY_kk(1,:),YY_kk(3,:),-YY_kk(2,:),['o' colors(rem(kk-1,6)+1)]); + hhh= mesh(YYrx,YYrz,-YYry); + set(hhh,'edgecolor',colors(rem(kk-1,6)+1),'linewidth',1); + text(uu(1),uu(3),-uu(2),num2str(kk),'fontsize',14,'color',colors(rem(kk-1,6)+1)); + +end; + +figure(4);rotate3d on; +axis('equal'); +title('Extrinsic parameters'); +%view(60,30); +view(a,b); +hold off; + + + +% Reproject the patterns on the images, and compute the pixel errors: + +% Reload the images if necessary + +if ~exist('I_1'), + ima_read_calib; + if no_image_file, + return; + end; +end; + + +ex = []; % Global error vector +x = []; % Detected corners on the image plane +y = []; % Reprojected points + +for kk = 1:n_ima, + + eval(['omckk = omc_' num2str(kk) ';']); + eval(['Tckk = Tc_' num2str(kk) ';']); + + Rkk = rodrigues(omckk); + + eval(['y_' num2str(kk) ' = project2_oulu(X_' num2str(kk) ',Rkk,Tckk,fc,cc,kc);']); + + eval(['ex_' num2str(kk) ' = x_' num2str(kk) ' -y_' num2str(kk) ';']); + + eval(['x_kk = x_' num2str(kk) ';']); + + figure(4+kk); + eval(['I = I_' num2str(kk) ';']); + image(I); hold on; + colormap(gray(256)); + title(['Image ' num2str(kk) ' - Image points (+) and reprojected grid points (o)']); + eval(['plot(x_' num2str(kk) '(1,:)+1,x_' num2str(kk) '(2,:)+1,''r+'');']); + eval(['plot(y_' num2str(kk) '(1,:)+1,y_' num2str(kk) '(2,:)+1,''' colors(rem(kk-1,6)+1) 'o'');']); + zoom on; + hold off; + + + eval(['ex = [ex ex_' num2str(kk) '];']); + eval(['x = [x x_' num2str(kk) '];']); + eval(['y = [y y_' num2str(kk) '];']); + +end; + + +figure(5+n_ima); +for kk = 1:n_ima, + eval(['plot(ex_' num2str(kk) '(1,:),ex_' num2str(kk) '(2,:),''' colors(rem(kk-1,6)+1) '+'');']); + hold on; +end; +hold off; +axis('equal'); +title('Reprojection error (in pixel)'); +xlabel('x'); +ylabel('y'); + +err_std = std(ex')'; + +fprintf(1,'Pixel error: err = [ %3.5f %3.5f]\n\n',err_std); diff --git a/SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/ima_read_calib.m b/SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/ima_read_calib.m new file mode 100755 index 0000000..09cef59 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/ima_read_calib.m @@ -0,0 +1,107 @@ + +if ~exist('calib_name'), + data_calib; +end; + +check_active_images; + +images_read = active_images; + +image_numbers = first_num:n_ima-1+first_num; + +no_image_file = 0; + +i = 1; + +while (i <= n_ima), % & (~no_image_file), + + if active_images(i), + + %fprintf(1,'Loading image %d...\n',i); + + if ~type_numbering, + number_ext = num2str(image_numbers(i)); + else + number_ext = sprintf(['%.' num2str(N_slots) 'd'],image_numbers(i)); + end; + + ima_name = [calib_name number_ext '.' format_image] + + if i == ind_active(1), + fprintf(1,'Loading image '); + end; + + if exist(ima_name), + + fprintf(1,'%d...',i); + + if format_image(1) == 'p', + Ii = double(pgmread(ima_name)); + else + if format_image(1) == 'r', + Ii = readras(ima_name); + else + Ii = double(imread(ima_name)); + end; + end; + + if size(Ii,3)>1, + Ii = Ii(:,:,2); + end; + + eval(['I_' num2str(i) ' = Ii;']); + + else + + fprintf(1,'%d...',i); + + images_read(i) = 0; + + no_image_file = 1; + + end; + + end; + + i = i+1; + +end; + + +if no_image_file, + + fprintf(1,'\nWARNING! Cannot load calibration images\n'); + +else + + fprintf(1,'\n'); + + if size(I_1,1)~=480, + small_calib_image = 1; + else + small_calib_image = 0; + end; + + [Hcal,Wcal] = size(I_1); % size of the calibration image + + [ny,nx] = size(I_1); + + clickname = []; + + map = gray(256); + + %string_save = 'save calib_data n_ima type_numbering N_slots image_numbers format_image calib_name Hcal Wcal nx ny map small_calib_image'; + + %eval(string_save); + + disp('done'); + %click_calib; + +end; + +if ~exist('map'), map = gray(256); end; + + + + + diff --git a/SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/init_calib_param.m b/SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/init_calib_param.m new file mode 100755 index 0000000..92e14be --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/init_calib_param.m @@ -0,0 +1,210 @@ +%init_calib_param +% +%Initialization of the intrinsic and extrinsic parameters. +%Runs as a script. +% +%This function is obsolete with init_intrinsic_param called from go_calib_optim +% +%INPUT: x_1,x_2,x_3,...: Feature locations on the images +% X_1,X_2,X_3,...: Corresponding grid coordinates +% +%OUTPUT: fc: Camera focal length +% cc: Principal point coordinates +% kc: Distortion coefficients +% KK: The camera matrix (containing fc and cc) +% omc_1,omc_2,omc_3,...: 3D rotation vectors attached to the grid positions in space +% Tc_1,Tc_2,Tc_3,...: 3D translation vectors attached to the grid positions in space +% Rc_1,Rc_2,Rc_3,...: 3D rotation matrices corresponding to the omc vectors +% +%Method: Compute the planar homographies H_1, H_2, H_3, ... and computes +% the focal length fc from orthogonal vanishing points constraint. +% The principal point cc is assumed at the center of the image. +% Assumes no image distortion (kc = [0;0;0;0]) +% Once the intrinsic parameters are estimated, the extrinsic parameters +% are computed for each image. +% +%Note: The row vector active_images consists of zeros and ones. To deactivate an image, set the +% corresponding entry in the active_images vector to zero. +% +% +%Important functions called within that program: +% +%compute_homography.m: Computes the planar homography between points on the grid in 3D, and the image plane. +% +%compute_extrinsic.m: Computes the location of a grid assuming known intrinsic parameters. +% This function is called at the initialization step. + + + + +check_active_images; + +if ~exist(['x_' num2str(ind_active(1)) ]), + click_calib; +end; + + +fprintf(1,'\nInitialization of the calibration parameters - Number of images: %d\n',length(ind_active)); + + +% Initialize the homographies: + +for kk = 1:n_ima, + eval(['x_kk = x_' num2str(kk) ';']); + eval(['X_kk = X_' num2str(kk) ';']); + if (isnan(x_kk(1,1))), + if active_images(kk), + fprintf(1,'WARNING: Cannot calibrate with image %d. Need to extract grid corners first.\n',kk) + fprintf(1,' Set active_images(%d)=1; and run Extract grid corners.\n',kk) + end; + active_images(kk) = 0; + end; + if active_images(kk), + eval(['H_' num2str(kk) ' = compute_homography(x_kk,X_kk(1:2,:));']); + else + eval(['H_' num2str(kk) ' = NaN*ones(3,3);']); + end; +end; + +check_active_images; + +% initial guess for principal point and distortion: + +if ~exist('nx'), [ny,nx] = size(I); end; + +c_init = [nx;ny]/2 - 0.5; % initialize at the center of the image +k_init = [0;0;0;0]; % initialize to zero (no distortion) + + + +% Compute explicitely the focal length using all the (mutually orthogonal) vanishing points +% note: The vanihing points are hidden in the planar collineations H_kk + +A = []; +b = []; + +% matrix that subtract the principal point: +Sub_cc = [1 0 -c_init(1);0 1 -c_init(2);0 0 1]; + +for kk=1:n_ima, + + if active_images(kk), + + eval(['Hkk = H_' num2str(kk) ';']); + + Hkk = Sub_cc * Hkk; + + % Extract vanishing points (direct and diagonals): + + V_hori_pix = Hkk(:,1); + V_vert_pix = Hkk(:,2); + V_diag1_pix = (Hkk(:,1)+Hkk(:,2))/2; + V_diag2_pix = (Hkk(:,1)-Hkk(:,2))/2; + + V_hori_pix = V_hori_pix/norm(V_hori_pix); + V_vert_pix = V_vert_pix/norm(V_vert_pix); + V_diag1_pix = V_diag1_pix/norm(V_diag1_pix); + V_diag2_pix = V_diag2_pix/norm(V_diag2_pix); + + a1 = V_hori_pix(1); + b1 = V_hori_pix(2); + c1 = V_hori_pix(3); + + a2 = V_vert_pix(1); + b2 = V_vert_pix(2); + c2 = V_vert_pix(3); + + a3 = V_diag1_pix(1); + b3 = V_diag1_pix(2); + c3 = V_diag1_pix(3); + + a4 = V_diag2_pix(1); + b4 = V_diag2_pix(2); + c4 = V_diag2_pix(3); + + A_kk = [a1*a2 b1*b2; + a3*a4 b3*b4]; + + b_kk = -[c1*c2;c3*c4]; + + + A = [A;A_kk]; + b = [b;b_kk]; + + end; + +end; + + +% use all the vanishing points to estimate focal length: + +f_init = sqrt(abs(1./(inv(A'*A)*A'*b))); % if using a two-focal model for initial guess + +%f_init = sqrt(b'*(sum(A')') / (b'*b)) * ones(2,1); % if single focal length model is used + + +% Global calibration matrix (initial guess): + +KK = [f_init(1) 0 c_init(1);0 f_init(2) c_init(2); 0 0 1]; +inv_KK = inv(KK); + + +cc = c_init; +fc = f_init; +kc = k_init; + + +% Computing of the extrinsic parameters (from the collineations) + +for kk = 1:n_ima, + + if active_images(kk), + + + eval(['x_kk = x_' num2str(kk) ';']); + eval(['X_kk = X_' num2str(kk) ';']); + + [omckk,Tckk] = compute_extrinsic(x_kk,X_kk,fc,cc,kc); + + Rckk = rodrigues(omc_kk); + + else + + omckk = NaN*ones(3,1); + Tckk = NaN*ones(3,1); + Rckk = NaN*ones(3,3); + + end; + + eval(['omc_' num2str(kk) ' = omckk;']); + eval(['Rc_' num2str(kk) ' = Rckk;']); + eval(['Tc_' num2str(kk) ' = Tckk;']); + +end; + + +% Initialization of the parameters for global minimization: + +init_param = [f_init;k_init]; + +for kk = 1:n_ima, + eval(['init_param = [init_param; omc_' num2str(kk) '; Tc_' num2str(kk) '];']); +end; + +solution_init = [init_param;c_init]; + +solution = solution_init; + +comp_error_calib; + +fprintf(1,'\n\nCalibration parameters after initialization:\n\n'); +fprintf(1,'Focal Length: fc = [ %3.5f %3.5f]\n',fc); +fprintf(1,'Principal point: cc = [ %3.5f %3.5f]\n',cc); +fprintf(1,'Distortion: kc = [ %3.5f %3.5f %3.5f %3.5f]\n',kc); +fprintf(1,'Pixel error: err = [ %3.5f %3.5f]\n\n',err_std); + + +%%%%%%%%%%%%%%%%%%%% GRAPHICAL OUTPUT %%%%%%%%%%%%%%%%%%%%%%%% + +%graphout_calib; + diff --git a/SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/init_intrinsic_param.m b/SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/init_intrinsic_param.m new file mode 100755 index 0000000..eac21ba --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/init_intrinsic_param.m @@ -0,0 +1,153 @@ +%init_intrinsic_param +% +%Initialization of the intrinsic parameters. +%Runs as a script. +% +%INPUT: x_1,x_2,x_3,...: Feature locations on the images +% X_1,X_2,X_3,...: Corresponding grid coordinates +% +%OUTPUT: fc: Camera focal length +% cc: Principal point coordinates +% kc: Distortion coefficients +% KK: The camera matrix (containing fc and cc) +% +%Method: Computes the planar homographies H_1, H_2, H_3, ... and computes +% the focal length fc from orthogonal vanishing points constraint. +% The principal point cc is assumed at the center of the image. +% Assumes no image distortion (kc = [0;0;0;0]) +% +%Note: The row vector active_images consists of zeros and ones. To deactivate an image, set the +% corresponding entry in the active_images vector to zero. +% +% +%Important function called within that program: +% +%compute_homography.m: Computes the planar homography between points on the grid in 3D, and the image plane. +% +% +%VERY IMPORTANT: This function works onyl with 2D rigs. +%In the future, a more general function will be there (working with 3D rigs as well). + + + +check_active_images; + +if ~exist(['x_' num2str(ind_active(1)) ]), + click_calib; +end; + + +fprintf(1,'\nInitialization of the intrinsic parameters - Number of images: %d\n',length(ind_active)); + + +% Initialize the homographies: + +for kk = 1:n_ima, + eval(['x_kk = x_' num2str(kk) ';']); + eval(['X_kk = X_' num2str(kk) ';']); + if (isnan(x_kk(1,1))), + if active_images(kk), + fprintf(1,'WARNING: Cannot calibrate with image %d. Need to extract grid corners first.\n',kk) + fprintf(1,' Set active_images(%d)=1; and run Extract grid corners.\n',kk) + end; + active_images(kk) = 0; + end; + if active_images(kk), + eval(['H_' num2str(kk) ' = compute_homography(x_kk,X_kk(1:2,:));']); + else + eval(['H_' num2str(kk) ' = NaN*ones(3,3);']); + end; +end; + +check_active_images; + +% initial guess for principal point and distortion: + +if ~exist('nx'), [ny,nx] = size(I); end; + +c_init = [nx;ny]/2 - 0.5; % initialize at the center of the image +k_init = [0;0;0;0]; % initialize to zero (no distortion) + + + +% Compute explicitely the focal length using all the (mutually orthogonal) vanishing points +% note: The vanihing points are hidden in the planar collineations H_kk + +A = []; +b = []; + +% matrix that subtract the principal point: +Sub_cc = [1 0 -c_init(1);0 1 -c_init(2);0 0 1]; + +for kk=1:n_ima, + + if active_images(kk), + + eval(['Hkk = H_' num2str(kk) ';']); + + Hkk = Sub_cc * Hkk; + + % Extract vanishing points (direct and diagonals): + + V_hori_pix = Hkk(:,1); + V_vert_pix = Hkk(:,2); + V_diag1_pix = (Hkk(:,1)+Hkk(:,2))/2; + V_diag2_pix = (Hkk(:,1)-Hkk(:,2))/2; + + V_hori_pix = V_hori_pix/norm(V_hori_pix); + V_vert_pix = V_vert_pix/norm(V_vert_pix); + V_diag1_pix = V_diag1_pix/norm(V_diag1_pix); + V_diag2_pix = V_diag2_pix/norm(V_diag2_pix); + + a1 = V_hori_pix(1); + b1 = V_hori_pix(2); + c1 = V_hori_pix(3); + + a2 = V_vert_pix(1); + b2 = V_vert_pix(2); + c2 = V_vert_pix(3); + + a3 = V_diag1_pix(1); + b3 = V_diag1_pix(2); + c3 = V_diag1_pix(3); + + a4 = V_diag2_pix(1); + b4 = V_diag2_pix(2); + c4 = V_diag2_pix(3); + + A_kk = [a1*a2 b1*b2; + a3*a4 b3*b4]; + + b_kk = -[c1*c2;c3*c4]; + + + A = [A;A_kk]; + b = [b;b_kk]; + + end; + +end; + + +% use all the vanishing points to estimate focal length: + +f_init = sqrt(abs(1./(inv(A'*A)*A'*b))); % if using a two-focal model for initial guess + +%f_init = sqrt(b'*(sum(A')') / (b'*b)) * ones(2,1); % if single focal length model is used + + +% Global calibration matrix (initial guess): + +KK = [f_init(1) 0 c_init(1);0 f_init(2) c_init(2); 0 0 1]; +inv_KK = inv(KK); + + +cc = c_init; +fc = f_init; +kc = k_init; + + +fprintf(1,'\n\nCalibration parameters after initialization:\n\n'); +fprintf(1,'Focal Length: fc = [ %3.5f %3.5f]\n',fc); +fprintf(1,'Principal point: cc = [ %3.5f %3.5f]\n',cc); +fprintf(1,'Distortion: kc = [ %3.5f %3.5f %3.5f %3.5f]\n\n',kc); diff --git a/SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/is3D.m b/SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/is3D.m new file mode 100755 index 0000000..ab00b3d --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/is3D.m @@ -0,0 +1,19 @@ +function test = is3D(X), + + +Np = size(X,2); + +%% Check for planarity of the structure: + +X_mean = mean(X')'; + +Y = X - (X_mean*ones(1,Np)); + +YY = Y*Y'; + +[U,S,V] = svd(YY); + +r = S(3,3)/S(2,2); + +test = (r > 1e-3); + diff --git a/SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/loading_calib.m b/SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/loading_calib.m new file mode 100755 index 0000000..a0f50d2 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/loading_calib.m @@ -0,0 +1,10 @@ +if ~exist('Calib_Results.mat'), + fprintf(1,'\nCalibration file Calib_Results.mat not found!\n'); + return; +end; + +fprintf(1,'\nLoading calibration results from Calib_Results.mat\n'); + +load Calib_Results + +fprintf(1,'done\n'); diff --git a/SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/loadinr.m b/SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/loadinr.m new file mode 100755 index 0000000..91b6f89 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/loadinr.m @@ -0,0 +1,52 @@ +%LOADINR Load an INRIMAGE format file +% +% LOADINR(filename, im) +% +% Load an INRIA image format file and return it as a matrix +% +% SEE ALSO: saveinr +% +% Copyright (c) Peter Corke, 1999 Machine Vision Toolbox for Matlab + + +% Peter Corke 1996 + +function im = loadinr(fname, im) + + fid = fopen(fname, 'r'); + + s = fgets(fid); + if strcmp(s(1:12), '#INRIMAGE-4#') == 0, + error('not INRIMAGE format'); + end + + % not very complete, only looks for the X/YDIM keys + while 1, + s = fgets(fid); + n = length(s) - 1; + if s(1) == '#', + break + end + if strcmp(s(1:5), 'XDIM='), + cols = str2num(s(6:n)); + end + if strcmp(s(1:5), 'YDIM='), + rows = str2num(s(6:n)); + end + if strcmp(s(1:4), 'CPU='), + if strcmp(s(5:n), 'sun') == 0, + error('not sun data ordering'); + end + end + + end + disp(['INRIMAGE format file ' num2str(rows) ' x ' num2str(cols)]) + + % now the binary data + fseek(fid, 256, 'bof'); + [im count] = fread(fid, [cols rows], 'float32'); + im = im'; + if count ~= (rows*cols), + error('file too short'); + end + fclose(fid); diff --git a/SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/loadpgm.m b/SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/loadpgm.m new file mode 100755 index 0000000..9386111 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/loadpgm.m @@ -0,0 +1,89 @@ +%LOADPGM Load a PGM image +% +% I = loadpgm(filename) +% +% Returns a matrix containing the image loaded from the PGM format +% file filename. Handles ASCII (P2) and binary (P5) PGM file formats. +% +% If the filename has no extension, and open fails, a '.pgm' will +% be appended. +% +% +% Copyright (c) Peter Corke, 1999 Machine Vision Toolbox for Matlab + + +% Peter Corke 1994 + +function I = loadpgm(file) + white = [' ' 9 10 13]; % space, tab, lf, cr + white = setstr(white); + + fid = fopen(file, 'r'); + if fid < 0, + fid = fopen([file '.pgm'], 'r'); + end + if fid < 0, + error('Couldn''t open file'); + end + + magic = fread(fid, 2, 'char'); + while 1 + c = fread(fid,1,'char'); + if c == '#', + fgetl(fid); + elseif ~any(c == white) + fseek(fid, -1, 'cof'); % unputc() + break; + end + end + cols = fscanf(fid, '%d', 1); + while 1 + c = fread(fid,1,'char'); + if c == '#', + fgetl(fid); + elseif ~any(c == white) + fseek(fid, -1, 'cof'); % unputc() + break; + end + end + rows = fscanf(fid, '%d', 1); + while 1 + c = fread(fid,1,'char'); + if c == '#', + fgetl(fid); + elseif ~any(c == white) + fseek(fid, -1, 'cof'); % unputc() + break; + end + end + maxval = fscanf(fid, '%d', 1); + while 1 + c = fread(fid,1,'char'); + if c == '#', + fgetl(fid); + elseif ~any(c == white) + fseek(fid, -1, 'cof'); % unputc() + break; + end + end + if magic(1) == 'P', + if magic(2) == '2', + disp(['ASCII PGM file ' num2str(rows) ' x ' num2str(cols)]) + I = fscanf(fid, '%d', [cols rows])'; + elseif magic(2) == '5', + disp(['Binary PGM file ' num2str(rows) ' x ' num2str(cols)]) + if maxval == 1, + fmt = 'unint1'; + elseif maxval == 15, + fmt = 'uint4'; + elseif maxval == 255, + fmt = 'uint8'; + elseif maxval == 2^32-1, + fmt = 'uint32'; + end + I = fread(fid, [cols rows], fmt)'; + else + disp('Not a PGM file'); + end + end + fclose(fid); diff --git a/SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/loadppm.m b/SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/loadppm.m new file mode 100755 index 0000000..6dd7ca4 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/loadppm.m @@ -0,0 +1,101 @@ +%LOADPPM Load a PPM image +% +% [R,G,B] = loadppm(filename) +% +% Returns a matrix containing the image loaded from the PPM format +% file filename. Handles ASCII (P3) and binary (P6) PPM file formats. +% +% If the filename has no extension, and open fails, a '.ppm' and +% '.pnm' extension will be tried. +% +% SEE ALSO: saveppm loadpgm +% +% Copyright (c) Peter Corke, 1999 Machine Vision Toolbox for Matlab + + +% Peter Corke 1994 + +function [R,G,B] = loadppm(file) + white = [' ' 9 10 13]; % space, tab, lf, cr + white = setstr(white); + + fid = fopen(file, 'r'); + if fid < 0, + fid = fopen([file '.ppm'], 'r'); + end + if fid < 0, + fid = fopen([file '.pnm'], 'r'); + end + if fid < 0, + error('Couldn''t open file'); + end + + magic = fread(fid, 2, 'char'); + while 1 + c = fread(fid,1,'char'); + if c == '#', + fgetl(fid); + elseif ~any(c == white) + fseek(fid, -1, 'cof'); % unputc() + break; + end + end + cols = fscanf(fid, '%d', 1); + while 1 + c = fread(fid,1,'char'); + if c == '#', + fgetl(fid); + elseif ~any(c == white) + fseek(fid, -1, 'cof'); % unputc() + break; + end + end + rows = fscanf(fid, '%d', 1); + while 1 + c = fread(fid,1,'char'); + if c == '#', + fgetl(fid); + elseif ~any(c == white) + fseek(fid, -1, 'cof'); % unputc() + break; + end + end + maxval = fscanf(fid, '%d', 1); + while 1 + c = fread(fid,1,'char'); + if c == '#', + fgetl(fid); + elseif ~any(c == white) + fseek(fid, -1, 'cof'); % unputc() + break; + end + end + if magic(1) == 'P', + if magic(2) == '3', + disp(['ASCII PPM file ' num2str(rows) ' x ' num2str(cols)]) + I = fscanf(fid, '%d', [cols*3 rows]); + elseif magic(2) == '6', + disp(['Binary PPM file ' num2str(rows) ' x ' num2str(cols)]) + if maxval == 1, + fmt = 'unint1'; + elseif maxval == 15, + fmt = 'uint4'; + elseif maxval == 255, + fmt = 'uint8'; + elseif maxval == 2^32-1, + fmt = 'uint32'; + end + I = fread(fid, [cols*3 rows], fmt); + else + disp('Not a PPM file'); + end + end + % + % now the matrix has interleaved columns of R, G, B + % + I = I'; + size(I) + R = I(:,1:3:(cols*3)); + G = I(:,2:3:(cols*3)); + B = I(:,3:3:(cols*3)); + fclose(fid); diff --git a/SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/mean_std_robust.m b/SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/mean_std_robust.m new file mode 100755 index 0000000..0d18a62 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/mean_std_robust.m @@ -0,0 +1,7 @@ +function [m,s] = mean_std_robust(x); + +x = x(:); + +m = median(x); + +s = median(abs(x - m))*1.4836; diff --git a/SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/multi_error_oulu.m b/SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/multi_error_oulu.m new file mode 100755 index 0000000..8657158 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/multi_error_oulu.m @@ -0,0 +1,49 @@ +function ex = multi_error_oulu(param,n_ima,cc); + +global X_1 x_1 X_2 x_2 X_3 x_3 X_4 x_4 X_5 x_5 X_6 x_6 X_7 x_7 X_8 x_8 X_9 x_9 X_10 x_10 X_11 x_11 X_12 x_12 X_13 x_13 X_14 x_14 X_15 x_15 X_16 x_16 X_17 x_17 X_18 x_18 X_19 x_19 X_20 x_20 X_21 x_21 X_22 x_22 X_23 x_23 X_24 x_24 X_25 x_25 X_26 x_26 X_27 x_27 X_28 x_28 X_29 x_29 X_30 x_30 + +fc = param(1:2); +kc = param(3:6); +%ppc = param(5:6); + +if length(param) > 6*n_ima + 3 + 3, + + cc = param(6*n_ima + 4 + 3:6*n_ima + 5 + 3); + + if length(param) > 6*n_ima + 5 + 3, + + c_d = param(6*n_ima + 6 + 3 :6*n_ima + 7 + 3); + + else + + c_d = [0;0]; + + end; + +else + + c_d = [0;0]; + +end; + + + +ex = []; + +%keyboard; + +for kk = 1:n_ima, + + omckk = param(4+6*(kk-1) + 3:6*kk + 3); + + Tckk = param(6*kk+1 + 3:6*kk+3 + 3); + + Rkk = rodrigues(omckk); + + eval(['ykk = project2_oulu(X_' num2str(kk) ',Rkk,Tckk,fc,cc,kc);']); + + eval(['exkk = x_' num2str(kk) ' -ykk;']); + + ex = [ex;exkk(:)]; + +end; diff --git a/SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/normalize.m b/SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/normalize.m new file mode 100755 index 0000000..0a37378 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/normalize.m @@ -0,0 +1,32 @@ +function [xn] = normalize(x_kk,fc,cc,kc), + +%normalize +% +%[xn] = normalize(x_kk,fc,cc,kc) +% +%Computes the normalized coordinates xn given the pixel coordinates x_kk +%and the intrinsic camera parameters fc, cc and kc. +% +%INPUT: x_kk: Feature locations on the images +% fc: Camera focal length +% cc: Principal point coordinates +% kc: Distortion coefficients +% +%OUTPUT: xn: Normalized feature locations on the image plane (a 2XN matrix) +% +%Important functions called within that program: +% +%comp_distortion_oulu: undistort pixel coordinates. + + + +% First subtract principal point, and divide by the focal length: + +x_distort = [(x_kk(1,:) - cc(1))/fc(1);(x_kk(2,:) - cc(2))/fc(2)]; + + +%Compensate for lens distortion: + +xn = comp_distortion_oulu(x_distort,kc); + + diff --git a/SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/pgmread.m b/SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/pgmread.m new file mode 100755 index 0000000..c96ccb7 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/pgmread.m @@ -0,0 +1,26 @@ +function img = pgmread(filename) +% function img = pgmread(filename) +% this is my version of pgmread for the pgm file created by XV. +% +% this program also corrects for the shifts in the image from pm file. + +fid = fopen(filename,'r'); +fscanf(fid, 'P5\n'); +cmt = '#'; +while findstr(cmt, '#'), + cmt = fgets(fid); + if length(findstr(cmt, '#')) ~= 1, + YX = sscanf(cmt, '%d %d'); + y = YX(1); x = YX(2); + end +end + +%fgets(fid); + +%img = fscanf(fid,'%d',size); +%img = img'; + +img = fread(fid,[y,x],'uint8'); +img = img'; +fclose(fid); + diff --git a/SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/project2_oulu.m b/SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/project2_oulu.m new file mode 100755 index 0000000..c5c4a34 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/project2_oulu.m @@ -0,0 +1,53 @@ +function [x] = project2_oulu(X,R,T,f,t,k) +%PROJECT Subsidiary to calib + +% (c) Pietro Perona -- March 24, 1994 +% California Institute of Technology +% Pasadena, CA +% +% Renamed because project exists in matlab 5.2!!! +% Now uses the more elaborate intrinsic model from Oulu + + + +[m,n] = size(X); + +Y = R*X + T*ones(1,n); +Z = Y(3,:); + +f = f(:); %% make a column vector +if length(f)==1, + f = [f f]'; +end; + +x = (Y(1:2,:) ./ (ones(2,1) * Z)) ; + + +radius_2 = x(1,:).^2 + x(2,:).^2; + +if length(k) > 1, + + radial_distortion = 1 + ones(2,1) * ((k(1) * radius_2) + (k(2) * radius_2.^2)); + + if length(k) < 4, + + delta_x = zeros(2,n); + + else + + delta_x = [2*k(3)*x(1,:).*x(2,:) + k(4)*(radius_2 + 2*x(1,:).^2) ; + k(3) * (radius_2 + 2*x(2,:).^2)+2*k(4)*x(1,:).*x(2,:)]; + + end; + + +else + + radial_distortion = 1 + ones(2,1) * ((k(1) * radius_2)); + + delta_x = zeros(2,n); + +end; + + +x = (x .* radial_distortion + delta_x).* (f * ones(1,n)) + t*ones(1,n); diff --git a/SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/project_points.m b/SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/project_points.m new file mode 100755 index 0000000..1823490 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/project_points.m @@ -0,0 +1,276 @@ +function [xp,dxpdom,dxpdT,dxpdf,dxpdc,dxpdk] = project_points(X,om,T,f,c,k) + +%project_points.m +% +%[xp,dxpdom,dxpdT,dxpdf,dxpdc,dxpdk] = project_points(X,om,T,f,c,k) +% +%Projects a 3D structure onto the image plane. +% +%INPUT: X: 3D structure in the world coordinate frame (3xN matrix for N points) +% (om,T): Rigid motion parameters between world coordinate frame and camera reference frame +% om: rotation vector (3x1 vector); T: translation vector (3x1 vector) +% f: camera focal length in units of horizontal and vertical pixel units (2x1 vector) +% c: principal point location in pixel units (2x1 vector) +% k: Distortion coefficients (radial and tangential) (4x1 vector) +% +%OUTPUT: xp: Projected pixel coordinates (2xN matrix for N points) +% dxpdom: Derivative of xp with respect to om ((2N)x3 matrix) +% dxpdT: Derivative of xp with respect to T ((2N)x3 matrix) +% dxpdf: Derivative of xp with respect to f ((2N)x2 matrix) +% dxpdc: Derivative of xp with respect to c ((2N)x2 matrix) +% dxpdk: Derivative of xp with respect to k ((2N)x4 matrix) +% +%Definitions: +%Let P be a point in 3D of coordinates X in the world reference frame (stored in the matrix X) +%The coordinate vector of P in the camera reference frame is: Xc = R*X + T +%where R is the rotation matrix corresponding to the rotation vector om: R = rodrigues(om); +%call x, y and z the 3 coordinates of Xc: x = Xc(1); y = Xc(2); z = Xc(3); +%The pinehole projection coordinates of P is [a;b] where a=x/z and b=y/z. +%call r^2 = a^2 + b^2. +%The distorted point coordinates are: xd = [xx;yy] where: +% +%xx = a * (1 + kc(1)*r^2 + kc(2)*r^4) + 2*kc(3)*a*b + kc(4)*(r^2 + 2*a^2); +%yy = b * (1 + kc(1)*r^2 + kc(2)*r^4) + kc(3)*(r^2 + 2*b^2) + 2*kc(4)*a*b; +% +%The left terms correspond to radial distortion, the right terms correspond to tangential distortion +% +%Fianlly, convertion into pixel coordinates: The final pixel coordinates vector xp=[xxp;yyp] where: +% +%xxp = f(1)*xx + c(1) +%yyp = f(2)*yy + c(2) +% +% +%NOTE: About 90 percent of the code takes care fo computing the Jacobian matrices +% +% +%Important function called within that program: +% +%rodrigues.m: Computes the rotation matrix corresponding to a rotation vector +% +%rigid_motion.m: Computes the rigid motion transformation of a given structure + + + +if nargin < 6, + k = zeros(4,1); + if nargin < 5, + c = zeros(2,1); + if nargin < 4, + f = ones(2,1); + if nargin < 3, + T = zeros(3,1); + if nargin < 2, + om = zeros(3,1); + if nargin < 1, + error('Need at least a 3D structure to project (in project_points.m)'); + return; + end; + end; + end; + end; + end; +end; + + +[m,n] = size(X); + +[Y,dYdom,dYdT] = rigid_motion(X,om,T); + + +inv_Z = 1./Y(3,:); + +x = (Y(1:2,:) .* (ones(2,1) * inv_Z)) ; + + +bb = (-x(1,:) .* inv_Z)'*ones(1,3); +cc = (-x(2,:) .* inv_Z)'*ones(1,3); + + +dxdom = zeros(2*n,3); +dxdom(1:2:end,:) = ((inv_Z')*ones(1,3)) .* dYdom(1:3:end,:) + bb .* dYdom(3:3:end,:); +dxdom(2:2:end,:) = ((inv_Z')*ones(1,3)) .* dYdom(2:3:end,:) + cc .* dYdom(3:3:end,:); + +dxdT = zeros(2*n,3); +dxdT(1:2:end,:) = ((inv_Z')*ones(1,3)) .* dYdT(1:3:end,:) + bb .* dYdT(3:3:end,:); +dxdT(2:2:end,:) = ((inv_Z')*ones(1,3)) .* dYdT(2:3:end,:) + cc .* dYdT(3:3:end,:); + + +% Add distortion: + +r2 = x(1,:).^2 + x(2,:).^2; + + + +dr2dom = 2*((x(1,:)')*ones(1,3)) .* dxdom(1:2:end,:) + 2*((x(2,:)')*ones(1,3)) .* dxdom(2:2:end,:); +dr2dT = 2*((x(1,:)')*ones(1,3)) .* dxdT(1:2:end,:) + 2*((x(2,:)')*ones(1,3)) .* dxdT(2:2:end,:); + + +r4 = r2.^2; + +dr4dom = 2*((r2')*ones(1,3)) .* dr2dom; +dr4dT = 2*((r2')*ones(1,3)) .* dr2dT; + + +% Radial distortion: + +cdist = 1 + k(1) * r2 + k(2) * r4; + +dcdistdom = k(1) * dr2dom + k(2) * dr4dom; +dcdistdT = k(1) * dr2dT+ k(2) * dr4dT; +dcdistdk = [ r2' r4' zeros(n,2)]; + + +xd1 = x .* (ones(2,1)*cdist); + +dxd1dom = zeros(2*n,3); +dxd1dom(1:2:end,:) = (x(1,:)'*ones(1,3)) .* dcdistdom; +dxd1dom(2:2:end,:) = (x(2,:)'*ones(1,3)) .* dcdistdom; +coeff = (reshape([cdist;cdist],2*n,1)*ones(1,3)); +dxd1dom = dxd1dom + coeff.* dxdom; + +dxd1dT = zeros(2*n,3); +dxd1dT(1:2:end,:) = (x(1,:)'*ones(1,3)) .* dcdistdT; +dxd1dT(2:2:end,:) = (x(2,:)'*ones(1,3)) .* dcdistdT; +dxd1dT = dxd1dT + coeff.* dxdT; + +dxd1dk = zeros(2*n,4); +dxd1dk(1:2:end,:) = (x(1,:)'*ones(1,4)) .* dcdistdk; +dxd1dk(2:2:end,:) = (x(2,:)'*ones(1,4)) .* dcdistdk; + + + +% tangential distortion: + +a1 = 2.*x(1,:).*x(2,:); +a2 = r2 + 2*x(1,:).^2; +a3 = r2 + 2*x(2,:).^2; + +delta_x = [k(3)*a1 + k(4)*a2 ; + k(3) * a3 + k(4)*a1]; + + +ddelta_xdx = zeros(2*n,2*n); +aa = (2*k(3)*x(2,:)+6*k(4)*x(1,:))'*ones(1,3); +bb = (2*k(3)*x(1,:)+2*k(4)*x(2,:))'*ones(1,3); +cc = (6*k(3)*x(2,:)+2*k(4)*x(1,:))'*ones(1,3); + +ddelta_xdom = zeros(2*n,3); +ddelta_xdom(1:2:end,:) = aa .* dxdom(1:2:end,:) + bb .* dxdom(2:2:end,:); +ddelta_xdom(2:2:end,:) = bb .* dxdom(1:2:end,:) + cc .* dxdom(2:2:end,:); + +ddelta_xdT = zeros(2*n,3); +ddelta_xdT(1:2:end,:) = aa .* dxdT(1:2:end,:) + bb .* dxdT(2:2:end,:); +ddelta_xdT(2:2:end,:) = bb .* dxdT(1:2:end,:) + cc .* dxdT(2:2:end,:); + +ddelta_xdk = zeros(2*n,4); +ddelta_xdk(1:2:end,3) = a1'; +ddelta_xdk(1:2:end,4) = a2'; +ddelta_xdk(2:2:end,3) = a3'; +ddelta_xdk(2:2:end,4) = a1'; + + + +xd2 = xd1 + delta_x; + +dxd2dom = dxd1dom + ddelta_xdom ; +dxd2dT = dxd1dT + ddelta_xdT; +dxd2dk = dxd1dk + ddelta_xdk ; + + +% Pixel coordinates: + +xp = xd2 .* (f * ones(1,n)) + c*ones(1,n); + +coeff = reshape(f*ones(1,n),2*n,1); + +dxpdom = (coeff*ones(1,3)) .* dxd2dom; +dxpdT = (coeff*ones(1,3)) .* dxd2dT; +dxpdk = (coeff*ones(1,4)) .* dxd2dk; + +dxpdf = zeros(2*n,2); +dxpdf(1:2:end,1) = xd2(1,:)'; +dxpdf(2:2:end,2) = xd2(2,:)'; + +dxpdc = zeros(2*n,2); +dxpdc(1:2:end,1) = ones(n,1); +dxpdc(2:2:end,2) = ones(n,1); + + +return; + +% Test of the Jacobians: + +n = 10; + +X = 10*randn(3,n); +om = randn(3,1); +T = [10*randn(2,1);40]; +f = 1000*rand(2,1); +c = 1000*randn(2,1); +k = 0.5*randn(4,1); + + +[x,dxdom,dxdT,dxdf,dxdc,dxdk] = project_points(X,om,T,f,c,k); + + +% Test on om: NOT OK + +dom = 0.000000001 * norm(om)*randn(3,1); +om2 = om + dom; + +[x2] = project_points(X,om2,T,f,c,k); + +x_pred = x + reshape(dxdom * dom,2,n); + + +norm(x2-x)/norm(x2 - x_pred) + + +% Test on T: OK!! + +dT = 0.0001 * norm(T)*randn(3,1); +T2 = T + dT; + +[x2] = project_points(X,om,T2,f,c,k); + +x_pred = x + reshape(dxdT * dT,2,n); + + +norm(x2-x)/norm(x2 - x_pred) + + + +% Test on f: OK!! + +df = 0.001 * norm(f)*randn(2,1); +f2 = f + df; + +[x2] = project_points(X,om,T,f2,c,k); + +x_pred = x + reshape(dxdf * df,2,n); + + +norm(x2-x)/norm(x2 - x_pred) + + +% Test on c: OK!! + +dc = 0.01 * norm(c)*randn(2,1); +c2 = c + dc; + +[x2] = project_points(X,om,T,f,c2,k); + +x_pred = x + reshape(dxdc * dc,2,n); + +norm(x2-x)/norm(x2 - x_pred) + +% Test on k: OK!! + +dk = 0.001 * norm(4)*randn(4,1); +k2 = k + dk; + +[x2] = project_points(X,om,T,f,c,k2); + +x_pred = x + reshape(dxdk * dk,2,n); + +norm(x2-x)/norm(x2 - x_pred) diff --git a/SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/projectedGrid.m b/SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/projectedGrid.m new file mode 100755 index 0000000..561a7d0 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/projectedGrid.m @@ -0,0 +1,24 @@ +function [XX,H] = projectedGrid ( P1, P2, P3, P4 , nx, ny); + +% new formalism using homographies + +a00 = [P1;1]; +a10 = [P2;1]; +a11 = [P3;1]; +a01 = [P4;1]; + +% Compute the planart collineation: + +[H] = compute_collineation (a00, a10, a11, a01); + + +% Build the grid using the planar collineation: + +x_l = ((0:(nx-1))'*ones(1,ny))/(nx-1); +y_l = (ones(nx,1)*(0:(ny-1)))/(ny-1); + +pts = [x_l(:) y_l(:) ones(nx*ny,1)]'; + +XX = H*pts; + +XX = XX(1:2,:) ./ (ones(2,1)*XX(3,:)); diff --git a/SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/readras.m b/SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/readras.m new file mode 100755 index 0000000..fc1820b --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/readras.m @@ -0,0 +1,87 @@ +function [X, map] = readras(filename, ys, ye, xs, xe); +%READRAS Read an image file in sun raster format. +% READRAS('imagefile.ras') reads a "sun.raster" image file. +% [X, map] = READRAS('imagefile.ras') returns both the image and a +% color map, so that +% [X, map] = readras('imagefile.ras'); +% image(X) +% colormap(map) +% axis('equal') +% will display the result with the proper colors. +% NOTE: readras cannot deal with complicated color maps. +% In fact, Matlab doesn't quite allow to work with colormaps +% with more than 64 entries. +% + +%% +%% (C) Thomas K. Leung 3/30/93. +%% California Institute of Technology. +%% Modified by Andrea Mennucci to deal with color images +%% + +% PC and UNIX version of readras - Jean-Yves Bouguet - Dec. 1998 + +dot = max(find(filename == '.')); +suffix = filename(dot+1:dot+3); + +if(strcmp(suffix, 'ras')) % raster file format % + fp = fopen(filename, 'rb'); + if(fp<0) error(['Cannot open ' filename '.']), end + + %Read and crack the 32-byte header + fseek(fp, 4, -1); + + width = 2^24 * fread(fp, 1, 'uchar') + 2^16 * fread(fp, 1, 'uchar') + 2^8 * fread(fp, 1, 'uchar') + fread(fp, 1, 'uchar'); + + height = 2^24 * fread(fp, 1, 'uchar') + 2^16 * fread(fp, 1, 'uchar') + 2^8 * fread(fp, 1, 'uchar') + fread(fp, 1, 'uchar'); + + depth = 2^24 * fread(fp, 1, 'uchar') + 2^16 * fread(fp, 1, 'uchar') + 2^8 * fread(fp, 1, 'uchar') + fread(fp, 1, 'uchar'); + + length = 2^24 * fread(fp, 1, 'uchar') + 2^16 * fread(fp, 1, 'uchar') + 2^8 * fread(fp, 1, 'uchar') + fread(fp, 1, 'uchar'); + + type = 2^24 * fread(fp, 1, 'uchar') + 2^16 * fread(fp, 1, 'uchar') + 2^8 * fread(fp, 1, 'uchar') + fread(fp, 1, 'uchar'); + + maptype = 2^24 * fread(fp, 1, 'uchar') + 2^16 * fread(fp, 1, 'uchar') + 2^8 * fread(fp, 1, 'uchar') + fread(fp, 1, 'uchar'); + + maplen = 2^24 * fread(fp, 1, 'uchar') + 2^16 * fread(fp, 1, 'uchar') + 2^8 * fread(fp, 1, 'uchar') + fread(fp, 1, 'uchar'); + + maplen = maplen / 3; + + if maptype == 2 % RMT_RAW + map = fread(fp, [maplen, 3], 'uchar')/255; +% if maplen<64, map=[map',zeros(3,64-maplen)]';maplen=64; end; + elseif maptype == 1 % RMT_EQUAL_RGB + map(:,1) = fread(fp, [maplen], 'uchar'); + map(:,2) = fread(fp, [maplen], 'uchar'); + map(:,3) = fread(fp, [maplen], 'uchar'); + %maxmap = max(max(map)); + map = map/255; + if maplen<64, map=[map',zeros(3,64-maplen)]'; maplen=64; end; + else % RMT_NONE + map = []; + end +% if maplen>64, +% map=[map',zeros(3,256-maplen)]'; +% end; + + % Read the image + + if rem(width,2) == 1 + Xt = fread(fp, [width+1, height], 'uchar'); + X = Xt(1:width, :)'; + else + Xt = fread(fp, [width, height], 'uchar'); + X = Xt'; + end + X = X + 1; + fclose(fp); +else + error('Image file name must end in either ''ras'' or ''rast''.'); +end + + +if nargin == 5 + + X = X(ys:ye, xs:xe); + +end \ No newline at end of file diff --git a/SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/recomp_corner_calib.m b/SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/recomp_corner_calib.m new file mode 100755 index 0000000..e0af501 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/recomp_corner_calib.m @@ -0,0 +1,96 @@ +% Re-select te corners after calibration + +check_active_images; + +if ~exist(['y_' num2str(ind_active(1))]), + fprintf(1,'Need to calibrate once before before recomputing image corners. Maybe need to load Calib_Results.mat file.\n'); + return; +end; + +if ~exist(['I_' num2str(ind_active(1))]), + ima_read_calib; + if no_image_file, + disp('Cannot extract corners without images'); + return; + end; +end; + +fprintf(1,'\nRe-extraction of the grid corners on the images (after first calibration)\n'); + +disp('Window size for corner finder (wintx and winty):'); +wintx = input('wintx ([] = 5) = '); +if isempty(wintx), wintx = 5; end; +wintx = round(wintx); +winty = input('winty ([] = 5) = '); +if isempty(winty), winty = 5; end; +winty = round(winty); + +fprintf(1,'Window size = %dx%d\n',2*wintx+1,2*winty+1); + +ima_numbers = input('Number(s) of image(s) to process ([] = all images) = '); + +if isempty(ima_numbers), + ima_proc = 1:n_ima; +else + ima_proc = ima_numbers; +end; + +q_auto = input('Use the projection of 3D grid or manual click ([]=auto, other=manual): '); + +fprintf(1,'Processing image '); + +for kk = ima_proc; + + if active_images(kk), + + fprintf(1,'%d...',kk); + + if isempty(q_auto), + + eval(['I = I_' num2str(kk) ';']); + + eval(['y = y_' num2str(kk) ';']); + + xc = cornerfinder(y+1,I,winty,wintx); % the four corners + + eval(['wintx_' num2str(kk) ' = wintx;']); + eval(['winty_' num2str(kk) ' = winty;']); + + eval(['x_' num2str(kk) '= xc - 1;']); + + else + + fprintf(1,'\n'); + + click_ima_calib; + + end; + + else + + if ~exist(['omc_' num2str(kk)]), + + eval(['dX_' num2str(kk) ' = NaN;']); + eval(['dY_' num2str(kk) ' = NaN;']); + + eval(['wintx_' num2str(kk) ' = NaN;']); + eval(['winty_' num2str(kk) ' = NaN;']); + + eval(['x_' num2str(kk) ' = NaN*ones(2,1);']); + eval(['X_' num2str(kk) ' = NaN*ones(3,1);']); + + eval(['n_sq_x_' num2str(kk) ' = NaN;']); + eval(['n_sq_y_' num2str(kk) ' = NaN;']); + + end; + + end; + + +end; + +% Recompute the error: + +comp_error_calib; + +fprintf(1,'\ndone\n'); \ No newline at end of file diff --git a/SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/rect.m b/SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/rect.m new file mode 100755 index 0000000..d8b6366 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/rect.m @@ -0,0 +1,93 @@ +function [Irec] = rect(I,R,f,c,k,KK_new); + + +% Note: R is the motion of the points in space +% So: X2 = R*X where X: coord in the old reference frame, X2: coord in the new ref frame. + +[nr,nc] = size(I); + +Irec = 255*ones(nr,nc); + +[mx,my] = meshgrid(1:nc, 1:nr); +px = reshape(mx',nc*nr,1); +py = reshape(my',nc*nr,1); + +rays = inv(KK_new)*[(px - 1)';(py - 1)';ones(1,length(px))]; + + +% Rotation: (or affine transformation): + +rays2 = R'*rays; + + +x = [rays2(1,:)./rays2(3,:);rays2(2,:)./rays2(3,:)]; + +% Add distortion: + +k1 = k(1); +k2 = k(2); + +p1 = k(3); +p2 = k(4); + +r_2 = sum(x.^2); + +delta_x = [2*p1*x(1,:).*x(2,:) + p2*(r_2 + 2*x(1,:).^2) ; + p1 * (r_2 + 2*x(2,:).^2)+2*p2*x(1,:).*x(2,:)]; + +xd = (ones(2,1)*( 1 + k1 * r_2 + k2 * r_2.^2)) .* x + delta_x; + + +% Reconvert in pixels: + +px2 = f(1)*xd(1,:)+c(1); +py2 = f(2)*xd(2,:)+c(2); + + +% Interpolate between the closest pixels: + + +px_0 = floor(px2); +px_1 = px_0 + 1; +alpha_x = px2 - px_0; + +py_0 = floor(py2); +py_1 = py_0 + 1; +alpha_y = py2 - py_0; + +good_points = find((px_0 >= 0) & (px_1 <= (nc-1)) & (py_0 >= 0) & (py_1 <= (nr-1))); + +I_lu = I(px_0(good_points) * nr + py_0(good_points) + 1); +I_ru = I(px_1(good_points) * nr + py_0(good_points) + 1); +I_ld = I(px_0(good_points) * nr + py_1(good_points) + 1); +I_rd = I(px_1(good_points) * nr + py_1(good_points) + 1); + + +I_interp = (1 - alpha_y(good_points)).*((1 - alpha_x(good_points)).* I_lu + alpha_x(good_points) .* I_ru) + alpha_y(good_points) .* ((1 - alpha_x(good_points)).* I_ld + alpha_x(good_points) .* I_rd); + + +Irec((px(good_points)-1)*nr + py(good_points)) = I_interp; + + + +return; + + +% Convert in indices: + +fact = 3; + +[XX,YY]= meshgrid(1:nc,1:nr); +[XXi,YYi]= meshgrid(1:1/fact:nc,1:1/fact:nr); + +%tic; +Iinterp = interp2(XX,YY,I,XXi,YYi); +%toc + +[nri,nci] = size(Iinterp); + + +ind_col = round(fact*(f(1)*xd(1,:)+c(1)))+1; +ind_row = round(fact*(f(2)*xd(2,:)+c(2)))+1; + +good_points = find((ind_col >=1)&(ind_col<=nci)&(ind_row >=1)& (ind_row <=nri)); diff --git a/SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/reproject_calib.m b/SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/reproject_calib.m new file mode 100755 index 0000000..86b13f5 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/reproject_calib.m @@ -0,0 +1,92 @@ +%%%%%%%%%%%%%%%%%%%% REPROJECT ON THE IMAGES %%%%%%%%%%%%%%%%%%%%%%%% + +if ~exist('no_image'), + no_image = 0; +end; + +check_active_images; + + +% Color code for each image: + +colors = 'brgkcm'; + +% Reproject the patterns on the images, and compute the pixel errors: + +% Reload the images if necessary + +if ~exist(['omc_' num2str(ind_active(1)) ]), + fprintf(1,'Need to calibrate before showing image reprojection. Maybe need to load Calib_Results.mat file.\n'); + return; +end; + +if ~no_image, + if ~exist(['I_' num2str(ind_active(1)) ]'), + ima_read_calib; + if no_image_file, + fprintf(1,'WARNING: Do not show the original images\n'); %return; + end; + end; +else + no_image_file = 1; +end; + + + +ima_numbers = input('Number(s) of image(s) to show ([] = all images) = '); + +if isempty(ima_numbers), + ima_proc = 1:n_ima; +else + ima_proc = ima_numbers; +end; + + +figure(5); +for kk = ima_proc, %1:n_ima, + if active_images(kk) & eval(['~isnan(y_' num2str(kk) '(1,1))']), + eval(['plot(ex_' num2str(kk) '(1,:),ex_' num2str(kk) '(2,:),''' colors(rem(kk-1,6)+1) '+'');']); + hold on; + end; +end; +hold off; +axis('equal'); +title('Reprojection error (in pixel)'); +xlabel('x'); +ylabel('y'); +drawnow; + +set(5,'Name','error','NumberTitle','off'); + + + +for kk = ima_proc, + + if active_images(kk) & eval(['~isnan(y_' num2str(kk) '(1,1))']), + + if exist(['I_' num2str(kk)]), + eval(['I = I_' num2str(kk) ';']); + else + I = 255*ones(ny,nx); + end; + + figure(5+kk); + image(I); hold on; + colormap(gray(256)); + title(['Image ' num2str(kk) ' - Image points (+) and reprojected grid points (o)']); + eval(['plot(x_' num2str(kk) '(1,:)+1,x_' num2str(kk) '(2,:)+1,''r+'');']); + eval(['plot(y_' num2str(kk) '(1,:)+1,y_' num2str(kk) '(2,:)+1,''' colors(rem(kk-1,6)+1) 'o'');']); + zoom on; + hold off; + drawnow; + + set(5+kk,'Name',num2str(kk),'NumberTitle','off'); + + end; + +end; + + +err_std = std(ex')'; + +fprintf(1,'Pixel error: err = [ %3.5f %3.5f]\n\n',err_std); diff --git a/SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/rigid_motion.m b/SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/rigid_motion.m new file mode 100755 index 0000000..473405c --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/rigid_motion.m @@ -0,0 +1,66 @@ +function [Y,dYdom,dYdT] = rigid_motion(X,om,T); + +%rigid_motion.m +% +%[Y,dYdom,dYdT] = rigid_motion(X,om,T) +% +%Computes the rigid motion transformation Y = R*X+T, where R = rodrigues(om). +% +%INPUT: X: 3D structure in the world coordinate frame (3xN matrix for N points) +% (om,T): Rigid motion parameters between world coordinate frame and camera reference frame +% om: rotation vector (3x1 vector); T: translation vector (3x1 vector) +% +%OUTPUT: Y: 3D coordinates of the structure points in the camera reference frame (3xN matrix for N points) +% dYdom: Derivative of Y with respect to om ((3N)x3 matrix) +% dYdT: Derivative of Y with respect to T ((3N)x3 matrix) +% +%Definitions: +%Let P be a point in 3D of coordinates X in the world reference frame (stored in the matrix X) +%The coordinate vector of P in the camera reference frame is: Y = R*X + T +%where R is the rotation matrix corresponding to the rotation vector om: R = rodrigues(om); +% +%Important function called within that program: +% +%rodrigues.m: Computes the rotation matrix corresponding to a rotation vector + + + +if nargin < 3, + T = zeros(3,1); + if nargin < 2, + om = zeros(3,1); + if nargin < 1, + error('Need at least a 3D structure as input (in rigid_motion.m)'); + return; + end; + end; +end; + + +[R,dRdom] = rodrigues(om); + +[m,n] = size(X); + +Y = R*X + T*ones(1,n); + +if nargout > 1, + + +dYdR = zeros(3*n,9); +dYdT = zeros(3*n,3); + +dYdR(1:3:end,1:3:end) = X'; +dYdR(2:3:end,2:3:end) = X'; +dYdR(3:3:end,3:3:end) = X'; + +dYdT(1:3:end,1) = ones(n,1); +dYdT(2:3:end,2) = ones(n,1); +dYdT(3:3:end,3) = ones(n,1); + +dYdom = dYdR * dRdom; + +end; + + + + diff --git a/SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/rodrigues.m b/SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/rodrigues.m new file mode 100755 index 0000000..9d55337 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/rodrigues.m @@ -0,0 +1,217 @@ +function [out,dout]=rodrigues(in) + +% RODRIGUES Transform rotation matrix into rotation vector and viceversa. +% +% Sintax: [OUT]=RODRIGUES(IN) +% If IN is a 3x3 rotation matrix then OUT is the +% corresponding 3x1 rotation vector +% if IN is a rotation 3-vector then OUT is the +% corresponding 3x3 rotation matrix +% + +%% +%% Copyright (c) March 1993 -- Pietro Perona +%% California Institute of Technology +%% + +%% ALL CHECKED BY JEAN-YVES BOUGUET, October 1995. +%% FOR ALL JACOBIAN MATRICES !!! LOOK AT THE TEST AT THE END !! + +%% BUG when norm(om)=pi fixed -- April 6th, 1997; +%% Jean-Yves Bouguet + + +[m,n] = size(in); +%bigeps = 10e+4*eps; +bigeps = 10e+20*eps; + +if ((m==1) & (n==3)) | ((m==3) & (n==1)) %% it is a rotation vector + theta = norm(in); + if theta < eps + R = eye(3); + + %if nargout > 1, + + dRdin = [0 0 0; + 0 0 1; + 0 -1 0; + 0 0 -1; + 0 0 0; + 1 0 0; + 0 1 0; + -1 0 0; + 0 0 0]; + + %end; + + else + if n==length(in) in=in'; end; %% make it a column vec. if necess. + + %m3 = [in,theta] + + dm3din = [eye(3);in'/theta]; + + omega = in/theta; + + %m2 = [omega;theta] + + dm2dm3 = [eye(3)/theta -in/theta^2; zeros(1,3) 1]; + + alpha = cos(theta); + beta = sin(theta); + gamma = 1-cos(theta); + omegav=[[0 -omega(3) omega(2)];[omega(3) 0 -omega(1)];[-omega(2) omega(1) 0 ]]; + A = omega*omega'; + + %m1 = [alpha;beta;gamma;omegav;A]; + + dm1dm2 = zeros(21,4); + dm1dm2(1,4) = -sin(theta); + dm1dm2(2,4) = cos(theta); + dm1dm2(3,4) = sin(theta); + dm1dm2(4:12,1:3) = [0 0 0 0 0 1 0 -1 0; + 0 0 -1 0 0 0 1 0 0; + 0 1 0 -1 0 0 0 0 0]'; + + w1 = omega(1); + w2 = omega(2); + w3 = omega(3); + + dm1dm2(13:21,1) = [2*w1;w2;w3;w2;0;0;w3;0;0]; + dm1dm2(13: 21,2) = [0;w1;0;w1;2*w2;w3;0;w3;0]; + dm1dm2(13:21,3) = [0;0;w1;0;0;w2;w1;w2;2*w3]; + + R = eye(3)*alpha + omegav*beta + A*gamma; + + dRdm1 = zeros(9,21); + + dRdm1([1 5 9],1) = ones(3,1); + dRdm1(:,2) = omegav(:); + dRdm1(:,4:12) = beta*eye(9); + dRdm1(:,3) = A(:); + dRdm1(:,13:21) = gamma*eye(9); + + dRdin = dRdm1 * dm1dm2 * dm2dm3 * dm3din; + + + end; + out = R; + dout = dRdin; + + %% it is prob. a rot matr. + elseif ((m==n) & (m==3) & (norm(in' * in - eye(3)) < bigeps)... + & (abs(det(in)-1) < bigeps)) + R = in; + + + + tr = (trace(R)-1)/2; + dtrdR = [1 0 0 0 1 0 0 0 1]/2; + theta = real(acos(tr)); + + + if sin(theta) >= 1e-5, + + dthetadtr = -1/sqrt(1-tr^2); + + dthetadR = dthetadtr * dtrdR; + % var1 = [vth;theta]; + vth = 1/(2*sin(theta)); + dvthdtheta = -vth*cos(theta)/sin(theta); + dvar1dtheta = [dvthdtheta;1]; + + dvar1dR = dvar1dtheta * dthetadR; + + + om1 = [R(3,2)-R(2,3), R(1,3)-R(3,1), R(2,1)-R(1,2)]'; + + dom1dR = [0 0 0 0 0 1 0 -1 0; + 0 0 -1 0 0 0 1 0 0; + 0 1 0 -1 0 0 0 0 0]; + + % var = [om1;vth;theta]; + dvardR = [dom1dR;dvar1dR]; + + % var2 = [om;theta]; + om = vth*om1; + domdvar = [vth*eye(3) om1 zeros(3,1)]; + dthetadvar = [0 0 0 0 1]; + dvar2dvar = [domdvar;dthetadvar]; + + + out = om*theta; + domegadvar2 = [theta*eye(3) om]; + + dout = domegadvar2 * dvar2dvar * dvardR; + + + else + if tr > 0; % case norm(om)=0; + + out = [0 0 0]'; + + dout = [0 0 0 0 0 1/2 0 -1/2 0; + 0 0 -1/2 0 0 0 1/2 0 0; + 0 1/2 0 -1/2 0 0 0 0 0]; + else % case norm(om)=pi; %% fixed April 6th + + + out = theta * (sqrt((diag(R)+1)/2).*[1;2*(R(1,2:3)>=0)'-1]); + %keyboard; + + if nargout > 1, + fprintf(1,'WARNING!!!! Jacobian domdR undefined!!!\n'); + dout = NaN*ones(3,9); + end; + end; + end; + + else + error('Neither a rotation matrix nor a rotation vector were provided'); + end; + +return; + +%% test of the Jacobians: + +%%%% TEST OF dRdom: +om = randn(3,1); +dom = randn(3,1)/1000000; + +[R1,dR1] = rodrigues(om); +R2 = rodrigues(om+dom); + +R2a = R1 + reshape(dR1 * dom,3,3); + +gain = norm(R2 - R1)/norm(R2 - R2a) + +%%% TEST OF dOmdR: +om = randn(3,1); +R = rodrigues(om); +dom = randn(3,1)/10000; +dR = rodrigues(om+dom) - R; + +[omc,domdR] = rodrigues(R); +[om2] = rodrigues(R+dR); + +om_app = omc + domdR*dR(:); + +gain = norm(om2 - omc)/norm(om2 - om_app) + + +%%% OTHER BUG: (FIXED NOW!!!) + +omu = randn(3,1); +omu = omu/norm(omu) +om = pi*omu; +[R,dR]= rodrigues(om); +[om2] = rodrigues(R); +[om om2] + +%%% NORMAL OPERATION + +om = randn(3,1); +[R,dR]= rodrigues(om); +[om2] = rodrigues(R); +[om om2] + diff --git a/SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/rotation.m b/SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/rotation.m new file mode 100755 index 0000000..87ee2fe --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/rotation.m @@ -0,0 +1,23 @@ +function [] = rotation(st); + +if nargin < 1, + st= 1; +end; + + +fig = gcf; + +ax = gca; + +vv = get(ax,'view'); + +az = vv(1); +el = vv(2); + +for azi = az:-abs(st):az-360, + + set(ax,'view',[azi el]); + figure(fig); + drawnow; + +end; diff --git a/SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/run_error_analysis.m b/SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/run_error_analysis.m new file mode 100755 index 0000000..095e17e --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/run_error_analysis.m @@ -0,0 +1,65 @@ +%%% Program that launchs the complete + +for N_ima_active = 1:30, + + error_analysis; + +end; + + + +return; + + +f = []; +f_std = []; + +c = []; +c_std = []; + +k = []; +k_std = []; + +NN = 30; + +for rr = 1:NN, + + load(['Calib_Accuracies_' num2str(rr)]); + + [m1,s1] = mean_std_robust(fc_list(1,:)); + [m2,s2] = mean_std_robust(fc_list(2,:)); + + f = [f [m1;m2]]; + f_std = [f_std [s1;s2]]; + + [m1,s1] = mean_std_robust(cc_list(1,:)); + [m2,s2] = mean_std_robust(cc_list(2,:)); + + c = [c [m1;m2]]; + c_std = [c_std [s1;s2]]; + + [m1,s1] = mean_std_robust(kc_list(1,:)); + [m2,s2] = mean_std_robust(kc_list(2,:)); + [m3,s3] = mean_std_robust(kc_list(3,:)); + [m4,s4] = mean_std_robust(kc_list(4,:)); + + k = [k [m1;m2;m3;m4]]; + k_std = [k_std [s1;s2;s3;s4]]; + +end; + +figure(1); +errorbar([1:NN;1:NN]',f',f_std'); +figure(2); +errorbar([1:NN;1:NN]',c',c_std'); +figure(3); +errorbar([1:NN;1:NN;1:NN;1:NN]',k',k_std'); + +figure(4); +semilogy(f_std'); + +figure(5); +semilogy(c_std'); + +figure(6); +semilogy(k_std'); diff --git a/SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/saveinr.m b/SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/saveinr.m new file mode 100755 index 0000000..a176e39 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/saveinr.m @@ -0,0 +1,46 @@ +%SAVEINR Write an INRIMAGE format file +% +% SAVEINR(filename, im) +% +% Saves the specified image array in a INRIA image format file. +% +% SEE ALSO: loadinr +% +% Copyright (c) Peter Corke, 1999 Machine Vision Toolbox for Matlab + +% Peter Corke 1996 + +function saveinr(fname, im) + + fid = fopen(fname, 'w'); + [r,c] = size(im'); + + % build the header + hdr = []; + s = sprintf('#INRIMAGE-4#{\n'); + hdr = [hdr s]; + s = sprintf('XDIM=%d\n',c); + hdr = [hdr s]; + s = sprintf('YDIM=%d\n',r); + hdr = [hdr s]; + s = sprintf('ZDIM=1\n'); + hdr = [hdr s]; + s = sprintf('VDIM=1\n'); + hdr = [hdr s]; + s = sprintf('TYPE=float\n'); + hdr = [hdr s]; + s = sprintf('PIXSIZE=32\n'); + hdr = [hdr s]; + s = sprintf('SCALE=2**0\n'); + hdr = [hdr s]; + s = sprintf('CPU=sun\n#'); + hdr = [hdr s]; + + % make it 256 bytes long and write it + hdr256 = zeros(1,256); + hdr256(1:length(hdr)) = hdr; + fwrite(fid, hdr256, 'uchar'); + + % now the binary data + fwrite(fid, im', 'float32'); + fclose(fid) diff --git a/SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/savepgm.m b/SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/savepgm.m new file mode 100755 index 0000000..397f028 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/savepgm.m @@ -0,0 +1,22 @@ +%SAVEPGM Write a PGM format file +% +% SAVEPGM(filename, im) +% +% Saves the specified image array in a binary (P5) format PGM image file. +% +% SEE ALSO: loadpgm +% +% Copyright (c) Peter Corke, 1999 Machine Vision Toolbox for Matlab + + +% Peter Corke 1994 + +function savepgm(fname, im) + + fid = fopen(fname, 'w'); + [r,c] = size(im'); + fprintf(fid, 'P5\n'); + fprintf(fid, '%d %d\n', r, c); + fprintf(fid, '255\n'); + fwrite(fid, im', 'uchar'); + fclose(fid) diff --git a/SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/saveppm.m b/SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/saveppm.m new file mode 100755 index 0000000..0062ee0 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/saveppm.m @@ -0,0 +1,25 @@ +%SAVEPPM Write a PPM format file +% +% SAVEPPM(filename, r, g, b) +% +% Saves the specified red, green and blue planes in a binary (P6) +% format PPM image file. +% +% SEE ALSO: loadppm +% +% Copyright (c) Peter Corke, 1999 Machine Vision Toolbox for Matlab + + +% Peter Corke 1994 + +function saveppm(fname, R, G, B) + + fid = fopen(fname, 'w'); + [r,c] = size(R'); + fprintf(fid, 'P6\n'); + fprintf(fid, '%d %d\n', r, c); + fprintf(fid, '255\n'); + im = [R(:) G(:) B(:)]; + im = reshape(c,r); + fwrite(fid, im, 'uchar'); + fclose(fid) diff --git a/SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/saving_calib.m b/SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/saving_calib.m new file mode 100755 index 0000000..e0575e0 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/saving_calib.m @@ -0,0 +1,27 @@ +fprintf(1,'\nSaving calibration results under Calib_Results.mat\n'); + +check_active_images; + +if ~exist('solution_init'), solution_init = []; end; + +for kk = 1:n_ima, + if ~exist(['dX_' num2str(kk)]), eval(['dX_' num2str(kk) '= dX;']); end; + if ~exist(['dY_' num2str(kk)]), eval(['dY_' num2str(kk) '= dY;']); end; +end; + +if ~exist('param_list'), + param_list = solution; +end; + + +string_save = 'save Calib_Results param_list active_images ind_active fc kc cc ex x y solution sol_with_center solution_init wintx winty n_ima type_numbering N_slots small_calib_image first_num image_numbers format_image calib_name Hcal Wcal nx ny map dX_default dY_default KK inv_KK dX dY'; + +for kk = 1:n_ima, + string_save = [string_save ' X_' num2str(kk) ' x_' num2str(kk) ' y_' num2str(kk) ' ex_' num2str(kk) ' omc_' num2str(kk) ' Rc_' num2str(kk) ' Tc_' num2str(kk) ' H_' num2str(kk) ' n_sq_x_' num2str(kk) ' n_sq_y_' num2str(kk) ' wintx_' num2str(kk) ' winty_' num2str(kk) ' dX_' num2str(kk) ' dY_' num2str(kk)]; +end; + +%fprintf(1,'To load later click on Load\n'); + +fprintf(1,'done\n'); + +eval(string_save); diff --git a/SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/script_fit_distortion.m b/SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/script_fit_distortion.m new file mode 100755 index 0000000..c5e5430 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/script_fit_distortion.m @@ -0,0 +1,39 @@ + + satis_distort = 0; + + disp(['Estimated focal: ' num2str(f_g) ' pixels']); + + while ~satis_distort, + + k_g = input('Guess for distortion factor kc ([]=0): '); + + if isempty(k_g), k_g = 0; end; + + xy_corners_undist = comp_distortion2([x' - c_g(1);y'-c_g(2)]/f_g,k_g); + + xu = xy_corners_undist(1,:)'; + yu = xy_corners_undist(2,:)'; + + [XXu] = projectedGrid ( [xu(1);yu(1)], [xu(2);yu(2)],[xu(3);yu(3)], [xu(4);yu(4)],n_sq_x+1,n_sq_y+1); % The full grid + + XX = (ones(2,1)*(1 + k_g * sum(XXu.^2))) .* XXu; + XX(1,:) = f_g*XX(1,:)+c_g(1); + XX(2,:) = f_g*XX(2,:)+c_g(2); + + figure(2); + image(I); + colormap(map); + zoom on; + hold on; + %plot(f_g*XXu(1,:)+c_g(1),f_g*XXu(2,:)+c_g(2),'ro'); + plot(XX(1,:),XX(2,:),'r+'); + title('The red crosses should be on the grid corners...'); + hold off; + + satis_distort = input('Satisfied with distortion? ([]=no, other=yes) '); + + satis_distort = ~isempty(satis_distort); + + + end; + \ No newline at end of file diff --git a/SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/select_sol_no_center.m b/SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/select_sol_no_center.m new file mode 100755 index 0000000..15508e5 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/select_sol_no_center.m @@ -0,0 +1,19 @@ +%%% Selection of the calibration solution with center estimation + +if ~exist('sol_no_center'), + fprintf(1,'Need to calibrate before selecting solution without center. Maybe need to load Calib_Results.mat file.\n'); + return; +end; + +solution = sol_no_center; + +%%% Extraction of the final intrinsic and extrinsic paramaters: + +extract_parameters; +comp_error_calib; + +fprintf(1,'\n\nCalibration results without principal point estimation:\n\n'); +fprintf(1,'Focal Length: fc = [ %3.5f %3.5f]\n',fc); +fprintf(1,'Principal point: cc = [ %3.5f %3.5f]\n',cc); +fprintf(1,'Distortion: kc = [ %3.5f %3.5f %3.5f %3.5f]\n',kc); +fprintf(1,'Pixel error: err = [ %3.5f %3.5f]\n\n',err_std); diff --git a/SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/select_sol_no_center3D.m b/SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/select_sol_no_center3D.m new file mode 100755 index 0000000..070d81c --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/select_sol_no_center3D.m @@ -0,0 +1,20 @@ +%%% Selection of the calibration solution with center estimation + +solution = sol_no_center; + +%%% Extraction of the final intrinsic and extrinsic paramaters: + +extract_parameters3D; + + +fprintf(1,'\n\nCalibration results without principal point estimation:\n\n'); +fprintf(1,'Focal Length: fc = [ %3.5f %3.5f]\n',fc); +fprintf(1,'Principal point: cc = [ %3.5f %3.5f]\n',cc); +fprintf(1,'Distortion: kc = [ %3.5f %3.5f %3.5f %3.5f]\n',kc); + + +%%%%%%%%%%%%%%%%%%%% GRAPHICAL OUTPUT %%%%%%%%%%%%%%%%%%%%%%%% + +graphout_calib3D; + + diff --git a/SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/select_sol_with_center.m b/SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/select_sol_with_center.m new file mode 100755 index 0000000..2df9ba8 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/select_sol_with_center.m @@ -0,0 +1,19 @@ +%%% Selection of the calibration solution with center estimation + +if ~exist('sol_with_center'), + fprintf(1,'Need to calibrate before selecting solution with center. Maybe need to load Calib_Results.mat file.\n'); + return; +end; + +solution = sol_with_center; + +%%% Extraction of the final intrinsic and extrinsic paramaters: + +extract_parameters; +comp_error_calib; + +fprintf(1,'\n\nCalibration results with principal point estimation:\n\n'); +fprintf(1,'Focal Length: fc = [ %3.5f %3.5f]\n',fc); +fprintf(1,'Principal point: cc = [ %3.5f %3.5f]\n',cc); +fprintf(1,'Distortion: kc = [ %3.5f %3.5f %3.5f %3.5f]\n',kc); +fprintf(1,'Pixel error: err = [ %3.5f %3.5f]\n\n',err_std); diff --git a/SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/select_sol_with_center3D.m b/SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/select_sol_with_center3D.m new file mode 100755 index 0000000..eb6f4bf --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/select_sol_with_center3D.m @@ -0,0 +1,20 @@ +%%% Selection of the calibration solution with center estimation + +solution = sol_with_center; + +%%% Extraction of the final intrinsic and extrinsic paramaters: + +extract_parameters3D; + + +fprintf(1,'\n\nCalibration results with principal point estimation:\n\n'); +fprintf(1,'Focal Length: fc = [ %3.5f %3.5f]\n',fc); +fprintf(1,'Principal point: cc = [ %3.5f %3.5f]\n',cc); +fprintf(1,'Distortion: kc = [ %3.5f %3.5f %3.5f %3.5f]\n',kc); + + +%%%%%%%%%%%%%%%%%%%% GRAPHICAL OUTPUT %%%%%%%%%%%%%%%%%%%%%%%% + +graphout_calib3D; + + diff --git a/SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/startup.m b/SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/startup.m new file mode 100755 index 0000000..aad0fa4 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/startup.m @@ -0,0 +1,9 @@ +% Main camera calibration toolbox: + +calib_gui; + +%calib_gui; + +path(pwd,path); + +format compact diff --git a/SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/test_3d.m b/SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/test_3d.m new file mode 100755 index 0000000..9f442f4 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/test_3d.m @@ -0,0 +1,80 @@ +Rc_1 = rodrigues(omc_1); +Rc_2 = rodrigues(omc_2); +Rc_3 = rodrigues(omc_3); +Rc_4 = rodrigues(omc_4); +Rc_5 = rodrigues(omc_5); +Rc_6 = rodrigues(omc_6); +Rc_7 = rodrigues(omc_7); +Rc_8 = rodrigues(omc_8); +Rc_9 = rodrigues(omc_9); + +Rc_10 = rodrigues(omc_10); +Rc_11 = rodrigues(omc_11); +Rc_12 = rodrigues(omc_12); +Rc_13 = rodrigues(omc_13); +Rc_14 = rodrigues(omc_14); +Rc_15 = rodrigues(omc_15); +Rc_16 = rodrigues(omc_16); +Rc_17 = rodrigues(omc_17); +Rc_18 = rodrigues(omc_18); + + + +RR1 = Rc_1'*Rc_10; % should be rodrigues([0;pi/2;0]) +TT1 = Rc_1'*(Tc_10-Tc_1); % should be [dX*n_sq_x_1;0;0] + +Xr_1 = RR1 * X_10 + TT1*ones(1,length(X_10)); + +figure(1); +plot3(X_1(1,:),X_1(2,:),X_1(3,:),'r+'); hold on; +plot3(Xr_1(1,:),Xr_1(2,:),Xr_1(3,:),'g+'); +hold off; +axis('equal'); +rotate3d on; +view(0,0); +xlabel('x'); +ylabel('y'); +zlabel('z'); + +aaa = []; + +RR1 = Rc_1'*Rc_10; % should be rodrigues([0;pi/2;0]) +TT1 = Rc_1'*(Tc_10-Tc_1); % should be [dX*n_sq_x_1;0;0] +err = rodrigues(RR1) - [0;pi/2;0] +aaa = [aaa 2*sin(err(2)/2)*.33*1000]; + +RR2 = Rc_2'*Rc_11; % should be rodrigues([0;pi/2;0]) +TT2 = Rc_2'*(Tc_11-Tc_2); % should be [dX*n_sq_x_1;0;0] +err = rodrigues(RR2) - [0;pi/2;0] +aaa = [aaa 2*sin(err(2)/2)*.33*1000]; + +RR3 = Rc_3'*Rc_12; % should be rodrigues([0;pi/2;0]) +TT3 = Rc_3'*(Tc_12-Tc_3); % should be [dX*n_sq_x_1;0;0] +err = rodrigues(RR3) - [0;pi/2;0] +aaa = [aaa 2*sin(err(2)/2)*.33*1000]; + +RR4 = Rc_4'*Rc_13; % should be rodrigues([0;pi/2;0]) +TT4 = Rc_4'*(Tc_13-Tc_4); % should be [dX*n_sq_x_1;0;0] +err = rodrigues(RR4) - [0;pi/2;0] +aaa = [aaa 2*sin(err(2)/2)*.33*1000]; + +RR5 = Rc_5'*Rc_14; % should be rodrigues([0;pi/2;0]) +TT5 = Rc_5'*(Tc_14-Tc_5); % should be [dX*n_sq_x_1;0;0] +err = rodrigues(RR5) - [0;pi/2;0] +aaa = [aaa 2*sin(err(2)/2)*.33*1000]; + +RR6 = Rc_6'*Rc_15; % should be rodrigues([0;pi/2;0]) +TT6 = Rc_6'*(Tc_15-Tc_6); % should be [dX*n_sq_x_1;0;0] +err = rodrigues(RR6) - [0;pi/2;0] +aaa = [aaa 2*sin(err(2)/2)*.33*1000]; + +RR7 = Rc_7'*Rc_16; % should be rodrigues([0;pi/2;0]) +TT7 = Rc_7'*(Tc_16-Tc_7); % should be [dX*n_sq_x_1;0;0] +err = rodrigues(RR7) - [0;pi/2;0] +aaa = [aaa 2*sin(err(2)/2)*.33*1000]; + +RR8 = Rc_8'*Rc_17; % should be rodrigues([0;pi/2;0]) +TT8 = Rc_8'*(Tc_17-Tc_8); % should be [dX*n_sq_x_1;0;0] +err = rodrigues(RR8) - [0;pi/2;0] +aaa = [aaa 2*sin(err(2)/2)*.33*1000]; + diff --git a/SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/undistort_image.m b/SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/undistort_image.m new file mode 100755 index 0000000..6393d78 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/undistort_image.m @@ -0,0 +1,88 @@ +%%% INPUT THE IMAGE FILE NAME: + +dir; + +fprintf(1,'\n'); +disp('Program that undistort an image'); +disp('The intrinsic camera parameters are assumed to be known (previously computed)'); + +fprintf(1,'\n'); +image_name = input('Image name (full name without extension): ','s'); + +format_image2 = '0'; + +while format_image2 == '0', + + format_image2 = input('Image format: ([]=''r''=''ras'', ''b''=''bmp'', ''t''=''tif'', ''p''=''pgm'', ''j''=''jpg'') ','s'); + + if isempty(format_image2), + format_image2 = 'ras'; + end; + + if lower(format_image2(1)) == 'b', + format_image2 = 'bmp'; + else + if lower(format_image2(1)) == 't', + format_image2 = 'tif'; + else + if lower(format_image2(1)) == 'p', + format_image2 = 'pgm'; + else + if lower(format_image2(1)) == 'j', + format_image2 = 'jpg'; + else + if lower(format_image2(1)) == 'r', + format_image2 = 'ras'; + else + disp('Invalid image format'); + format_image2 = '0'; % Ask for format once again + end; + end; + end; + end; + end; +end; + +ima_name = [image_name '.' format_image]; + + + +%%% READ IN IMAGE: + +if format_image(1) == 'p', + I = double(pgmread(ima_name)); +else + if format_image(1) == 'r', + I = readras(ima_name); + else + I = double(imread(ima_name)); + end; +end; + +if size(I,3)>1, + I = I(:,:,2); +end; + + +%% SHOW THE ORIGINAL IMAGE: + +figure(2); +image(I); +colormap(gray(256)); +title('Original image (with distortion) - Stored in array I'); +drawnow; + + +%% UNDISTORT THE IMAGE: + +fprintf(1,'Compututing the undistorted image...\n') + +[I2] = rect(I,eye(3),fc,cc,kc,KK); + + +figure(3); +image(I2); +colormap(gray(256)); +title('Undistorted image - Stored in array I2'); +drawnow; + diff --git a/SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/writeras.m b/SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/writeras.m new file mode 100755 index 0000000..c7eb7bc --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj/writeras.m @@ -0,0 +1,105 @@ +function writeras(filename, image, map); +%WRITERAS Write an image file in sun raster format. +% WRITERAS('imagefile.ras', image_matrix, map) writes a +% "sun.raster" image file. + +% Written by Thomas K. Leung 3/30/93. +% @ California Institute of Technology. + + +% PC and UNIX version of writeras - Jean-Yves Bouguet - Dec. 1998 + +dot = max(find(filename == '.')); +suffix = filename(dot+1:dot+3); + +if nargin < 3, + map = []; +end; + +if(strcmp(suffix, 'ras')) + %Write header + + fp = fopen(filename, 'wb'); + if(fp < 0) error(['Cannot open ' filename '.']), end + + [height, width] = size(image); + image = image - 1; + mapsize = size(map, 1)*size(map,2); + %fwrite(fp, ... + % [1504078485, width, height, 8, height*width, 1, 1, mapsize], ... + % 'long'); + + + zero_str = '00000000'; + + % MAGIC NUMBER: + + + fwrite(fp,89,'uchar'); + fwrite(fp,166,'uchar'); + fwrite(fp,106,'uchar'); + fwrite(fp,149,'uchar'); + + width_str = dec2hex(width); + width_str = [zero_str(1:8-length(width_str)) width_str]; + + for ii = 1:2:7, + fwrite(fp,hex2dec(width_str(ii:ii+1)),'uchar'); + end; + + + height_str = dec2hex(height); + height_str = [zero_str(1:8-length(height_str)) height_str]; + + for ii = 1:2:7, + fwrite(fp,hex2dec(height_str(ii:ii+1)),'uchar'); + end; + + fwrite(fp,0,'uchar'); + fwrite(fp,0,'uchar'); + fwrite(fp,0,'uchar'); + fwrite(fp,8,'uchar'); + + ll = height*width; + ll_str = dec2hex(ll); + ll_str = [zero_str(1:8-length(ll_str)) ll_str]; + + for ii = 1:2:7, + fwrite(fp,hex2dec(ll_str(ii:ii+1)),'uchar'); + end; + + fwrite(fp,0,'uchar'); + fwrite(fp,0,'uchar'); + fwrite(fp,0,'uchar'); + fwrite(fp,1,'uchar'); + fwrite(fp,0,'uchar'); + fwrite(fp,0,'uchar'); + fwrite(fp,0,'uchar'); + fwrite(fp,~~mapsize,'uchar'); + + mapsize_str = dec2hex(mapsize); + mapsize_str = [zero_str(1:8-length(mapsize_str)) mapsize_str]; + + %keyboard; + + for ii = 1:2:7, + fwrite(fp,hex2dec(mapsize_str(ii:ii+1)),'uchar'); + end; + + + if mapsize ~= 0 + map = min(255, fix(255*map)); + fwrite(fp, map, 'uchar'); + end + if rem(width,2) == 1 + image = [image'; zeros(1, height)]'; + top = 255 * ones(size(image)); + fwrite(fp, min(top,image)', 'uchar'); + else + top = 255 * ones(size(image)); + fwrite(fp, min(top,image)', 'uchar'); + end + fclose(fp); +else + error('Image file name must end in either ''ras'' or ''rast''.'); +end diff --git a/SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj2/TOOLBOX_calib.tar b/SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj2/TOOLBOX_calib.tar new file mode 100755 index 0000000..36d5de9 Binary files /dev/null and b/SD-VBS/common/toolbox/toolbox_basic/calib_bouguetj2/TOOLBOX_calib.tar differ diff --git a/SD-VBS/common/toolbox/toolbox_basic/common/Ncut_IC.m b/SD-VBS/common/toolbox/toolbox_basic/common/Ncut_IC.m new file mode 100755 index 0000000..d612780 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/common/Ncut_IC.m @@ -0,0 +1,26 @@ +function [v,d] = Ncut_IC(I,nb_radius_IC); +% +% [v,d] = Ncut_IC(I,nb_radius_IC); +% + +if nargin<2, + nb_radius_IC = 5; +end + +I = I/max(I(:)); + +eg_par = [16,2, 21,3]; eg_th = 0; + +nv = 11; reg_fac = 0.01; + +[ex,ey,egx,egy,eg_par,eg_th,emag,ephase] = quadedgep(I,eg_par,eg_th); + + +nb_radius_IC= 10; +sample_rate = 0.2; +disp('setupW\n'); +[w_i,w_j] = cimgnbmap(size(I),nb_radius_IC,sample_rate); +w = affinityic(emag,ephase,w_i,w_j); +disp('computeNcut'); +[v,d] = ncut(w,nv,[],reg_fac); + diff --git a/SD-VBS/common/toolbox/toolbox_basic/common/Ncut_IC_m.m b/SD-VBS/common/toolbox/toolbox_basic/common/Ncut_IC_m.m new file mode 100755 index 0000000..146acf9 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/common/Ncut_IC_m.m @@ -0,0 +1,42 @@ +function [v,d] = Ncut_IC_m(I,mask,nb_radius_IC,sig_IC); +% +% [v,d] = Ncut_IC_m(I,mask,nb_radius_IC,sig_IC); +% + +if nargin<2, + mask = ones(size(I)); +end + +if nargin<3, + nb_radius_IC = 10; +end + +if nargin<4, + sig_IC = 0.03; +end + +%%% normalize the image +I = I/max(I(:)); + +%%% edge detecting parameter, [num_ori, sig, win_size, enlongation factor] +eg_par = [6,2, 21,3]; eg_th = 0.01; + +%% number of eigenvectors+ regulization factors +nv = 10; reg_fac = 0.0; + +%% compute the edge response +[ex,ey,egx,egy,eg_par,eg_th,emag,ephase] = quadedgep(I,eg_par,eg_th); + +%%% setup Wij connection pattern +sample_rate = 0.1; +[w_i,w_j] = cimgnbmap(size(I),nb_radius_IC,sample_rate); + +%%% compute Wij with IC +emag = mask.*emag; +w = affinityic(emag,ephase,w_i,w_j,sig_IC); + +%show_dist_w(I,w); +%%% running Ncut +[v,d] = ncut(w,nv); + +v = reshape(v,size(I,1),size(I,2),size(v,2)); diff --git a/SD-VBS/common/toolbox/toolbox_basic/common/Ncut_IC_m2.m b/SD-VBS/common/toolbox/toolbox_basic/common/Ncut_IC_m2.m new file mode 100755 index 0000000..9668b19 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/common/Ncut_IC_m2.m @@ -0,0 +1,51 @@ +function [v,d] = Ncut_IC_m(I,mask,nb_radius_IC,sig_IC); +% +% [v,d] = Ncut_IC_m(I,mask,nb_radius_IC,sig_IC); +% + +if nargin<2, + mask = ones(size(I)); +end + +if nargin<3, + nb_radius_IC = 10; +end + +if nargin<4, + sig_IC = 0.03; +end + +%%% normalize the image +I = I/max(I(:)); + +%%% edge detecting parameter, [num_ori, sig, win_size, enlongation factor] +eg_par = [6,2, 21,3]; eg_th = 0.01; + +%% number of eigenvectors+ regulization factors +nv = 10; reg_fac = 0.0; + +%% compute the edge response +[nr,nc,nb] = size(I); +emag = zeros(nr,nc); +ephase = zeros(nr,nc); +for j=1:nb, + [ex,ey,egx,egy,eg_par,eg_th,emag1,ephase1] = quadedgep(I(:,:,j),eg_par,eg_th); + mask = emag1>emag; + ephase = ephase+ mask.*ephase1; + emag = emag + mask.*emag1; +end + + +%%% setup Wij connection pattern +sample_rate = 0.1; +[w_i,w_j] = cimgnbmap(size(I),nb_radius_IC,sample_rate); + +%%% compute Wij with IC +emag = mask.*emag; +w = affinityic(emag,ephase,w_i,w_j,sig_IC); + +%show_dist_w(I,w); +%%% running Ncut +[v,d] = ncut(w,nv); + +v = reshape(v,size(I,1),size(I,2),size(v,2)); diff --git a/SD-VBS/common/toolbox/toolbox_basic/common/affinityic.c b/SD-VBS/common/toolbox/toolbox_basic/common/affinityic.c new file mode 100755 index 0000000..e48762a --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/common/affinityic.c @@ -0,0 +1,186 @@ +/*================================================================ +* function w = affinityic(emag,ephase,pi,pj,sigma) +* Input: +* emag = edge strength at each pixel +* ephase = edge phase at each pixel +* [pi,pj] = index pair representation for MALTAB sparse matrices +* sigma = sigma for IC energy +* Output: +* w = affinity with IC at [pi,pj] +* + +% test sequence +f = synimg(10); +[i,j] = cimgnbmap(size(f),2); +[ex,ey,egx,egy] = quadedgep(f); +a = affinityic(ex,ey,egx,egy,i,j) +show_dist_w(f,a); + +* Jianbo Shi, Stella X. Yu, Nov 19, 2001. +*=================================================================*/ + +# include "mex.h" +# include "math.h" + +void mexFunction( + int nargout, + mxArray *out[], + int nargin, + const mxArray *in[] +) +{ + /* declare variables */ + int nr, nc, np, total; + int i, j, k, ix, iy, jx, jy, ii, jj, iip1, jjp1, iip2, jjp2, step; + double sigma, di, dj, a, z, maxori, phase1, phase2, slope; + int *ir, *jc; + unsigned long *pi, *pj; + double *emag, *ephase, *w; + + /* check argument */ + if (nargin<4) { + mexErrMsgTxt("Four input arguments required"); + } + if (nargout>1) { + mexErrMsgTxt("Too many output arguments"); + } + + /* get edgel information */ + nr = mxGetM(in[0]); + nc = mxGetN(in[0]); + if ( nr*nc ==0 || nr != mxGetM(in[1]) || nc != mxGetN(in[1]) ) { + mexErrMsgTxt("Edge magnitude and phase shall be of the same image size"); + } + emag = mxGetPr(in[0]); + ephase = mxGetPr(in[1]); + np = nr * nc; + + /* get new index pair */ + if (!mxIsUint32(in[2]) | !mxIsUint32(in[3])) { + mexErrMsgTxt("Index pair shall be of type UINT32"); + } + if (mxGetM(in[3]) * mxGetN(in[3]) != np + 1) { + mexErrMsgTxt("Wrong index representation"); + } + pi = mxGetData(in[2]); + pj = mxGetData(in[3]); + + /* create output */ + out[0] = mxCreateSparse(np,np,pj[np],mxREAL); + if (out[0]==NULL) { + mexErrMsgTxt("Not enough memory for the output matrix"); + } + w = mxGetPr(out[0]); + ir = mxGetIr(out[0]); + jc = mxGetJc(out[0]); + + /* find my sigma */ + if (nargin<5) { + sigma = 0; + for (k=0; ksigma) { sigma = emag[k]; } + } + sigma = sigma / 10; + printf("sigma = %6.5f",sigma); + } else { + sigma = mxGetScalar(in[4]); + } + a = 1.0/ (sigma); + + /* computation */ + total = 0; + for (j=0; j= abs(dj)) { + slope = dj / di; + step = (iy>=jy) ? 1 : -1; + + iip1 = jy; + jjp1 = jx; + + + for (ii=0;ii maxori){ + maxori = z; + } + } + + iip1 = iip2; + jjp1 = jjp2; + phase1 = phase2; + } + + /* sample in j direction */ + } else { + slope = di / dj; + step = (ix>=jx) ? 1: -1; + + jjp1 = jx; + iip1 = jy; + + + for (jj=0;jj maxori){ + maxori = z; + } + + } + + iip1 = iip2; + jjp1 = jjp2; + phase1 = phase2; + } + } + + maxori = 0.5 * maxori*a; + maxori = exp(-maxori*maxori); + } + ir[total] = i; + + w[total] = maxori + 0.005; + total = total + 1; + + } /* i */ + } /* j */ + + jc[np] = total; +} diff --git a/SD-VBS/common/toolbox/toolbox_basic/common/affinityic.mexa64 b/SD-VBS/common/toolbox/toolbox_basic/common/affinityic.mexa64 new file mode 100755 index 0000000..e60b4d1 Binary files /dev/null and b/SD-VBS/common/toolbox/toolbox_basic/common/affinityic.mexa64 differ diff --git a/SD-VBS/common/toolbox/toolbox_basic/common/affinityic.mexglx b/SD-VBS/common/toolbox/toolbox_basic/common/affinityic.mexglx new file mode 100755 index 0000000..5edb5d8 Binary files /dev/null and b/SD-VBS/common/toolbox/toolbox_basic/common/affinityic.mexglx differ diff --git a/SD-VBS/common/toolbox/toolbox_basic/common/anisodiff.m b/SD-VBS/common/toolbox/toolbox_basic/common/anisodiff.m new file mode 100755 index 0000000..b576d8f --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/common/anisodiff.m @@ -0,0 +1,20 @@ +function [outimage] = anisodiff(inimage,iterations,K) +% [outimage] = anisodiff(inimage,iterations,K) +% Pietro's anisotropic diffusion routine + +lambda = 0.25; +outimage = inimage; [m,n] = size(inimage); + +rowC = [1:m]; rowN = [1 1:m-1]; rowS = [2:m m]; +colC = [1:n]; colE = [1 1:n-1]; colW = [2:n n]; + +for i=1:iterations, + deltaN = outimage(rowN,colC) - outimage(rowC,colC); + deltaE = outimage(rowC,colE) - outimage(rowC,colC); + + fluxN = deltaN .* exp( - ((1/K) * abs(deltaN)).^2 ); + fluxE = deltaE .* exp( - ((1/K) * abs(deltaE)).^2 ); + + outimage = outimage + lambda * (fluxN - fluxN(rowS,colC) + fluxE - fluxE(rowC,colW)); +end + diff --git a/SD-VBS/common/toolbox/toolbox_basic/common/bin.m b/SD-VBS/common/toolbox/toolbox_basic/common/bin.m new file mode 100755 index 0000000..e2c3c90 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/common/bin.m @@ -0,0 +1,39 @@ +function [i, nnbins] = bin(x, dx, x0, x1); +% +% [i, nbins] = bin(x, dx, x0, x1); +% +% Returns the vector of indices, starting from 1, +% corresponding to the chosen bin size, dx, +% start x0 and end x1. If x1 is omitted, x1 = max(x) - dx/2. +% If x0 is omitted, x0 = min(x) + dx/2. If dx is omitted, the data +% are divided into 10 classes. Note that outliers are not removed. +% +% Tested under MatLab 4.2, 5.0, and 5.1. +% + +% 17.1.97, Oyvind.Breivik@gfi.uib.no. +% +% Oyvind Breivik +% Department of Geophysics +% University of Bergen +% NORWAY + +N = 10; % Default is 10 classes + +if nargin < 2 + dx = (max(x) - min(x))/N; +end +if nargin < 3 + x0 = min(x) + dx/2; +end +if nargin < 4 + x1 = max(x) - dx/2; +end +nbins = round((x1 - x0)/dx) + 1; +i = round((x - x0)/dx) + 1; +%in = (i >= 1) & (i <= nbins); % Indices are within range [1, nbins]. +%i = i(in); + +if nargout > 1 + nnbins = nbins; +end diff --git a/SD-VBS/common/toolbox/toolbox_basic/common/cimgnbmap.c b/SD-VBS/common/toolbox/toolbox_basic/common/cimgnbmap.c new file mode 100755 index 0000000..1595b68 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/common/cimgnbmap.c @@ -0,0 +1,189 @@ +/*================================================================ +* function [i,j] = cimgnbmap([nr,nc], nb_r, sample_rate) +* computes the neighbourhood index matrix of an image, +* with each neighbourhood sampled. +* Input: +* [nr,nc] = image size +* nb_r = neighbourhood radius, could be [r_i,r_j] for i,j +* sample_rate = sampling rate, default = 1 +* Output: +* [i,j] = each is a column vector, give indices of neighbour pairs +* UINT32 type +* i is of total length of valid elements, 0 for first row +* j is of length nr * nc + 1 +* +* See also: imgnbmap.c, id2cind.m +* +* Examples: +* [i,j] = imgnbmap(10, 20); % [10,10] are assumed +* +* Stella X. Yu, Nov 12, 2001. + +% test sequence: +nr = 15; +nc = 15; +nbr = 1; +[i,j] = cimgnbmap([nr,nc], nbr); +mask = csparse(i,j,ones(length(i),1),nr*nc); +show_dist_w(rand(nr,nc),mask) + +*=================================================================*/ + +# include "mex.h" +# include "math.h" + +void mexFunction( + int nargout, + mxArray *out[], + int nargin, + const mxArray *in[] +) +{ + /* declare variables */ + int nr, nc, np, nb, total; + double *dim, sample_rate; + int r_i, r_j, a1, a2, b1, b2, self, neighbor; + int i, j, k, s, t, nsamp, th_rand, no_sample; + unsigned long *p, *qi, *qj; + + /* check argument */ + if (nargin < 2) { + mexErrMsgTxt("Two input arguments required"); + } + if (nargout> 2) { + mexErrMsgTxt("Too many output arguments."); + } + + /* get image size */ + i = mxGetM(in[0]); + j = mxGetN(in[0]); + dim = mxGetData(in[0]); + nr = (int)dim[0]; + if (j>1 || i>1) { + nc = (int)dim[1]; + } else { + nc = nr; + } + np = nr * nc; + + /* get neighbourhood size */ + i = mxGetM(in[1]); + j = mxGetN(in[1]); + dim = mxGetData(in[1]); + r_i = (int)dim[0]; + if (j>1 || i>1) { + r_j = (int)dim[1]; + } else { + r_j = r_i; + } + if (r_i<0) { r_i = 0; } + if (r_j<0) { r_j = 0; } + + /* get sample rate */ + if (nargin==3) { + sample_rate = (mxGetM(in[2])==0) ? 1: mxGetScalar(in[2]); + } else { + sample_rate = 1; + } + /* prepare for random number generator */ + if (sample_rate<1) { + srand( (unsigned)time( NULL ) ); + th_rand = (int)ceil((double)RAND_MAX * sample_rate); + no_sample = 0; + } else { + sample_rate = 1; + th_rand = RAND_MAX; + no_sample = 1; + } + + /* figure out neighbourhood size */ + + nb = (r_i + r_i + 1) * (r_j + r_j + 1); + if (nb>np) { + nb = np; + } + nb = (int)ceil((double)nb * sample_rate); + + /* intermediate data structure */ + p = mxCalloc(np * (nb+1), sizeof(unsigned long)); + if (p==NULL) { + mexErrMsgTxt("Not enough space for my computation."); + } + + /* computation */ + total = 0; + for (j=0; j=nc) { b2 = nc-1; } + + /* i range */ + a1 = i - r_i; + if (a1<0) { a1 = 0; } + a2 = i + r_i; + if (a2>=nr) { a2 = nr-1; } + + /* number of more samples needed */ + nsamp = nb - p[self]; + + k = 0; + t = b1; + s = i + 1; + if (s>a2) { + s = a1; + t = t + 1; + } + while (ka2) { + s = a1; + t = t + 1; + } + } /* k */ + + total = total + p[self]; + } /* i */ + } /* j */ + + /* i, j */ + out[0] = mxCreateNumericMatrix(total, 1, mxUINT32_CLASS, mxREAL); + out[1] = mxCreateNumericMatrix(np+1, 1, mxUINT32_CLASS, mxREAL); + qi = mxGetData(out[0]); + qj = mxGetData(out[1]); + if (out[0]==NULL || out[1]==NULL) { + mexErrMsgTxt("Not enough space for the output matrix."); + } + + total = 0; + for (j=0; j 1) + xy0 = dx; + dx = DX; +end + +if nargin < 3 + dx = DX; +end + +if (nargin == 4 & length(dy) > 1) + xy0 = dy; + dy = dx; +end +if nargin < 4 + dy = dx; +end + +nxy = length(xy0); +xy(1:nxy) = xy0; + +if (isnan(xy(4))) + xy(4) = max(y); +end +if (isnan(xy(3))) + xy(3) = min(y); +end +if (isnan(xy(2))) + xy(2) = max(x); +end +if (isnan(xy(1))) + xy(1) = min(x); +end +x0 = xy(1); x1 = xy(2); y0 = xy(3); y1 = xy(4); + +if (dx < 0) + dx = (x1 - x0)/abs(dx); +end +if (dy < 0) + dy = (y1 - y0)/abs(dy); +end + +ix = bin(x, dx, x0, x1); +iy = bin(y, dy, y0, y1); % bin data in (x,y)-space + +xvec = x0:dx:x1; +yvec = y0:dy:y1; + +nx = length(xvec); +ny = length(yvec); + +inx = (ix >= 1) & (ix <= nx); +iny = (iy >= 1) & (iy <= ny); +in = (inx & iny); +ix = ix(in); iy = iy(in); +N = length(ix); % how many datapoints are left now? + +rho = zeros(length(xvec), length(yvec)) + eps; + +for i = 1:N + rho(ix(i), iy(i)) = rho(ix(i), iy(i)) + 1; +end + +rho = rho/(N*dx*dy); % Density is n per dx per dy + +rho = rho'; % Get in shape + +if nargout == 0 + pcolor(xvec, yvec, sqrt(rho)); shading interp; axis image; + colorbar + colormap jet + xlabel(inputname(1)) + ylabel(inputname(2)) + dum = size(rho'); + str = sprintf('%d data points, grid: %dx%d', N, dum(1)-1, dum(2)-1); + title(str); +end + +if nargout > 0 + rrho = rho; +end + +if nargout > 1 + xxvec = xvec; + yyvec = yvec; +end diff --git a/SD-VBS/common/toolbox/toolbox_basic/common/find_edge.m b/SD-VBS/common/toolbox/toolbox_basic/common/find_edge.m new file mode 100755 index 0000000..4299c29 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/common/find_edge.m @@ -0,0 +1,24 @@ +function [edgemap,mag,th] = find_edge(I,sig,mag_thld) +% +% [edgemap,mag,th] = find_edge(I,sig,mag_thld) +% + +if nargin<2, + sig = 1; +end + +if nargin<3, + mag_thld = 1/30; +end + +I = I/max(I(:)); + +ismax = 1;r = 1; + +[gx,gy] = grad(I,sig); +[th,mag] = cart2pol(gy,gx); + +g = cat(3,gy,gx); +edgemap = nonmaxsup(g,ismax,r); +edgemap = edgemap.*(mag>mag_thld); + diff --git a/SD-VBS/common/toolbox/toolbox_basic/common/grad.m b/SD-VBS/common/toolbox/toolbox_basic/common/grad.m new file mode 100755 index 0000000..05fce39 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/common/grad.m @@ -0,0 +1,28 @@ +% gradient of an image +% coordinates (r, c) follow matrix convention; +% the gaussian is truncated at x = +- tail, and there are samples samples +% inbetween, where samples = hsamples * 2 + 1 + +function[gr,gc] = gradient(image, hsamples,cm) + +if nargin <3, + cm = 'same'; +end + +tail=4; +samples = hsamples * 2 + 1; + +x = linspace(-tail, tail, samples); +gauss = exp(-x.^2); +n = gauss * ones(samples,1); +gauss = gauss/n; + +gaussderiv = -x.*gauss; +n = -gaussderiv*linspace(1,samples,samples)'; +gaussderiv = gaussderiv/n; + +%gr = conv2(conv2(image, gaussderiv','valid'), gauss,'valid'); +%gc = conv2(conv2(image, gaussderiv,'valid'), gauss','valid'); + +gr = conv2(conv2(image, gaussderiv',cm), gauss,cm); +gc = conv2(conv2(image, gaussderiv,cm), gauss',cm); diff --git a/SD-VBS/common/toolbox/toolbox_basic/common/make_filterbank_even2.m b/SD-VBS/common/toolbox/toolbox_basic/common/make_filterbank_even2.m new file mode 100755 index 0000000..937f9bd --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/common/make_filterbank_even2.m @@ -0,0 +1,45 @@ +function FB = make_filterbank(num_ori,filter_scales,wsz,enlong) +% +% F = make_filterbank(num_ori,num_scale,wsz) +% + +if nargin<4, + enlong = 3; +end + +enlong = 2*enlong + +% definine filterbank +%num_ori=6; +%num_scale=3; + +num_scale = length(filter_scales); + +M1=wsz; % size in pixels +M2=M1; + +ori_incr=180/num_ori; +ori_offset=ori_incr/2; % helps with equalizing quantiz. error across filter set + +FB=zeros(M1,M2,num_ori,num_scale); + +% elongated filter set +counter = 1; + +for m=1:num_scale + for n=1:num_ori + % r=12 here is equivalent to Malik's r=3; + f=doog2(filter_scales(m),enlong,ori_offset+(n-1)*ori_incr,M1); + FB(:,:,n,m)=f; + end +end + +FB=reshape(FB,M1,M2,num_scale*num_ori); +total_num_filt=size(FB,3); + +for j=1:total_num_filt, + F = FB(:,:,j); + a = sum(sum(abs(F))); + FB(:,:,j) = FB(:,:,j)/a; +end + diff --git a/SD-VBS/common/toolbox/toolbox_basic/common/make_filterbank_odd2.m b/SD-VBS/common/toolbox/toolbox_basic/common/make_filterbank_odd2.m new file mode 100755 index 0000000..0059dca --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/common/make_filterbank_odd2.m @@ -0,0 +1,46 @@ +function FB = make_filterbank(num_ori,filter_scales,wsz,enlong) +% +% F = make_filterbank(num_ori,num_scale,wsz) +% + +if nargin<4, + enlong = 3; +end + +enlong = enlong*2; + +% definine filterbank +%num_ori=6; +%num_scale=3; + +num_scale = length(filter_scales); + +M1=wsz; % size in pixels +M2=M1; + +ori_incr=180/num_ori; +ori_offset=ori_incr/2; % helps with equalizing quantiz. error across filter set + +FB=zeros(M1,M2,num_ori,num_scale); + + +% elongated filter set +counter = 1; + +for m=1:num_scale + for n=1:num_ori + % r=12 here is equivalent to Malik's r=3; + f=doog1(filter_scales(m),enlong,ori_offset+(n-1)*ori_incr,M1); + FB(:,:,n,m)=f; + end +end + +FB=reshape(FB,M1,M2,num_scale*num_ori); +total_num_filt=size(FB,3); + +for j=1:total_num_filt, + F = FB(:,:,j); + a = sum(sum(abs(F))); + FB(:,:,j) = FB(:,:,j)/a; +end + diff --git a/SD-VBS/common/toolbox/toolbox_basic/common/max_supress2.m b/SD-VBS/common/toolbox/toolbox_basic/common/max_supress2.m new file mode 100755 index 0000000..05b5f11 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/common/max_supress2.m @@ -0,0 +1,59 @@ +function NMS = max_supress2(data,ismax); +% +% NMS = max_supress(data,ismax); +% +% data: [nr,nc,nfilter,nscale] +% of filter mag. map +% ismax: 1 local max, 0 local min +% + +[nr,nc,nfilter,nscale] = size(data); + +% set up the orthognal neighbourhood for each oriented filter +if nfilter == 6, + nbr_template=[1 1 1 0 -1 -1 + 0 1 1 1 1 1]; +else + nbr_template=[1 0 ; + 0 1]; +end + +%% for each scale, compute the dominate filter response +canny_dir_I = zeros(nr,nc,nscale); + +for m = 1:nscale, + [max_Ori_resp_I,Ori_sca_I] = max(data(:,:,:,m),[],3); + canny_dir_I(:,:,m) = Ori_sca_I; +end + +max_Ori_resp_small = max_Ori_resp_I(2:end-1,2:end-1); +canny_dir = canny_dir_I(2:end-1,2:end-1); + +%% + +NMS = zeros(nr,nc,nscale); + + +for m = 1:nscale, + + [x,y] = meshgrid(2:nc-1,2:nr-1); + xid = x(:)+nbr_template(2,canny_dir(:))'; + yid = y(:)+nbr_template(1,canny_dir(:))'; + id1 = (xid-1)*nr+yid; + + xid = x(:)-nbr_template(2,canny_dir(:))'; + yid = y(:)-nbr_template(1,canny_dir(:))'; + id2 = (xid-1)*nr+yid; + if ismax, + a = (max_Ori_resp_small(:)>max_Ori_resp_I(id1(:))) .* (max_Ori_resp_small(:)>max_Ori_resp_I(id2(:))); + NMS(2:end-1,2:end-1,m) = reshape(a,nr-2,nc-2); + NMS(:,:,m) = NMS(:,:,m).*max_Ori_resp_I; + else + a = (max_Ori_resp_small(:)0); + rr = wi.*(wi>0)-wr.*(wr<0); + + % decomposition + au = aa + aa'; + ad = aa - aa'; + ru = rr + rr'; + rd = rr - rr'; + + % construct equivalent matrices + x = sum(ru,2); + wr = au - ru + diag(x); + wi = ad + rd; + x = x + sum(au,2); + + % re-organize, add in offset and beta + z(:,j) = x + 2 * offset; + na = na + ( beta * (wr + offset) + sqrt(-1)* (2-beta) * wi ); + +end +z = sum(z,2); % diag(z) = single equivalent D + +% normalize +d = repmat(1./sqrt(z+eps),1,nc); +na = d.*na; +na = na.*d'; + +options.disp = 0; +%options.tol = 1e-10; +%options.maxit = 15; + +[v,s] = eigs(na,nv,sigma,options); +s = real(diag(s)); + +% project back to get the eigenvectors for the pair (a,d) +% a x = lambda d x +% na y = lambda y +% x = d^(-1/2) y + +v = v .* d(:,ones(nv,1)); diff --git a/SD-VBS/common/toolbox/toolbox_basic/common/nonmaxsup.m b/SD-VBS/common/toolbox/toolbox_basic/common/nonmaxsup.m new file mode 100755 index 0000000..d12301c --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/common/nonmaxsup.m @@ -0,0 +1,81 @@ +% function f = nonmaxsup(g,ismax,r) return extrema boolean map. +% Input: g = image, gradient image pair [x,y], or [x,y,g] in 3D matrix +% ismax (=1)/0 is for non maximum/minimum suppression +% r (=1) is the neighbourhood radius. +% Output: +% f = thinned extrema boolean map, where +% d (||gradient||) / d gradient = 0 + +% Stella X. Yu, 2000. + +function f = nonmaxsup(g,ismax,r) + +if nargin<2, + ismax = 1; +end + +if nargin<3, + r = 1; +end + +i = size(g,3); +if i==3, + x = g(:,:,1); + y = g(:,:,2); + g = g(:,:,3); +elseif i==2, + x = g(:,:,1); + y = g(:,:,2); + g = x.*x + y.*y; +else + [x,y] = gradient(g); +end + +% label angles into 4 directions +a = angle(x - sqrt(-1).*y); % [-pi,pi) +s = ceil((abs(a)+pi/8)./(pi/4)); +s(find(s==5)) = 1; +s(find(isnan(s))) = 1; + +% augment the image +[m,n] = size(g); +newm = m + r + r; +i = [g(:,1);g(:,end);g(1,:)';g(end,:)']; % image boundary +if ismax, + v = min(i) - 1; +else + v = max(i) + 1; +end +i = zeros(newm,r) + v; +j = zeros(r,n) + v; +newg = [i, [j; g; j;], i]; + +% k = index as the interior of the new image +i = [r+1:newm-r]'+ r*newm; +j = [0:n-1].*newm; +k = i(:,ones(1,n)) + j(ones(1,m),:); +k = k(:); + +% unit displacement vectors along gradient directions +d = [newm,newm-1,-1,-1-newm]'; % for 4 directions +d = d(s(:)); + +% non maximum suppression +f = ones(m*n,1); +g = g(:); +newd = 0; + +if ismax, + for i=1:r, + newd = newd + d; + f = f & (g>newg(k+newd)) & (g>newg(k-newd)); + end +else + for i=1:r, + newd = newd + d; + f = f & (g0); +have_value = [ j, 1-j ]; +j = 1; n_filter = have_value(j,:) * [par(j); def_par(j)]; +j = 2; n_scale = have_value(j,:) * [par(j); def_par(j)]; +j = 3; winsz = have_value(j,:) * [par(j); def_par(j)]; +j = 4; enlong = have_value(j,:) * [par(j); def_par(j)]; + +% always make filter size an odd number so that the results will not be skewed +j = winsz/2; +if not(j > fix(j) + 0.1), + winsz = winsz + 1; +end + +% filter the image with quadrature filters +FBo = make_filterbank_odd2(n_filter,n_scale,winsz,enlong); +FBe = make_filterbank_even2(n_filter,n_scale,winsz,enlong); +n = ceil(winsz/2); +f = [fliplr(I(:,2:n+1)), I, fliplr(I(:,c-n:c-1))]; +f = [flipud(f(2:n+1,:)); f; flipud(f(r-n:r-1,:))]; +FIo = fft_filt_2(f,FBo,1); +FIo = FIo(n+[1:r],n+[1:c],:); +FIe = fft_filt_2(f,FBe,1); +FIe = FIe(n+[1:r],n+[1:c],:); + +% compute the orientation energy and recover a smooth edge map +% pick up the maximum energy across scale and orientation +% even filter's output: as it is the second derivative, zero cross localize the edge +% odd filter's output: orientation +mag = sqrt(sum(FIo.^2,3)+sum(FIe.^2,3)); +mag_a = sqrt(FIo.^2+FIe.^2); +[tmp,max_id] = max(mag_a,[],3); +base_size = r * c; +id = [1:base_size]'; +mage = reshape(FIe(id+(max_id(:)-1)*base_size),[r,c]); +mage = (mage>0) - (mage<0); + +ori_incr=pi/n_filter; % to convert jshi's coords to conventional image xy +ori_offset=ori_incr/2; +theta = ori_offset+([1:n_filter]-1)*ori_incr; % orientation detectors +% [gx,gy] are image gradient in image xy coords, winner take all +mago = reshape(FIo(id+(max_id(:)-1)*base_size),[r,c]); +ori = theta(max_id); +ori = ori .* (mago>0) + (ori + pi).*(mago<0); +gy = mag .* cos(ori); +gx = -mag .* sin(ori); +g = cat(3,gx,gy); + +% phase map: edges are where the phase changes +mag_th = max(mag(:)) * threshold; +eg = (mag>mag_th); +h = eg & [(mage(2:r,:) ~= mage(1:r-1,:)); zeros(1,c)]; +v = eg & [(mage(:,2:c) ~= mage(:,1:c-1)), zeros(r,1)]; +[y,x] = find(h | v); +k = y + (x-1) * r; +h = h(k); +v = v(k); +y = y + h * 0.5; % i +x = x + v * 0.5; % j +t = h + v * r; +gx = g(k) + g(k+t); +k = k + (r * c); +gy = g(k) + g(k+t); + +% display +if 1, +%figure; showmask(I,mage<0); +figure(2); clf;showim(I,1); hold on; quiver(x,y,gx,gy); +%figure; showim(-I,1); hold on; quiver(i,j,ex,ey); +end diff --git a/SD-VBS/common/toolbox/toolbox_basic/common/readpcm.m b/SD-VBS/common/toolbox/toolbox_basic/common/readpcm.m new file mode 100755 index 0000000..ca736da --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/common/readpcm.m @@ -0,0 +1,12 @@ +function I = readpcm(filename) + +fid = fopen(filename,'r'); + +A = fscanf(fid,'%d\n',2); +I = fscanf(fid,'%c',A(2)*A(1)); +I = I'; +I = str2num(I); +I = reshape(I,A(2),A(1))'; + + +fclose(fid); \ No newline at end of file diff --git a/SD-VBS/common/toolbox/toolbox_basic/common/readpdm.m b/SD-VBS/common/toolbox/toolbox_basic/common/readpdm.m new file mode 100755 index 0000000..9a1068e --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/common/readpdm.m @@ -0,0 +1,8 @@ +function I = readpfm(filename) + +fid = fopen(filename,'r'); + +A = fscanf(fid,'%d',2); +I = fscanf(fid,'%d',[A(1),A(2)]); + +fclose(fid); diff --git a/SD-VBS/common/toolbox/toolbox_basic/common/readpfm.m b/SD-VBS/common/toolbox/toolbox_basic/common/readpfm.m new file mode 100755 index 0000000..48ecd78 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/common/readpfm.m @@ -0,0 +1,10 @@ +function I = readpfm(filename) + +fid = fopen(filename,'r'); + +A = fscanf(fid,'%d',2); +I = fscanf(fid,'%f',[A(1),A(2)]); + +%I = fscanf(fid,'%f',A(2)*A(1));I = reshape(I,A(1),A(2)); + +fclose(fid); diff --git a/SD-VBS/common/toolbox/toolbox_basic/common/renormalize.m b/SD-VBS/common/toolbox/toolbox_basic/common/renormalize.m new file mode 100755 index 0000000..5d84724 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/common/renormalize.m @@ -0,0 +1,32 @@ +function W2 = renormalize(W,nstep) +% +% keep renormalizing until W is almost double +% stocastic +% + +if nargin<2, + nstep = 5; +end + +n_node = size(W,1); + +for j=1:nstep, + fprintf(','); + % normalize row + D = sum(W,2); + D = 1./(D+eps); + W = W.*D(:,ones(1,n_node)); + + % normlize column + D = sum(W,1); + D = 1./(D+eps); + W = W.*D(ones(n_node,1),:); +end +fprintf('\n'); + + D = sum(W,2); + D = 1./(D+eps); + W2 = W.*D(:,ones(1,n_node)); + + + diff --git a/SD-VBS/common/toolbox/toolbox_basic/common/show_edge.m b/SD-VBS/common/toolbox/toolbox_basic/common/show_edge.m new file mode 100755 index 0000000..63b2f98 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/common/show_edge.m @@ -0,0 +1,11 @@ +function [id_i,id_j,ids] = show_edge(I,MI,thI); +% +% show_edge(I,MI,thI); +% + +[id_i,id_j,tmp] = find(MI); +ids = sub2ind(size(I),id_i,id_j); +clf;im(I);colormap(gray);hold on; +quiver(id_j,id_i,-sin(thI(ids)),cos(thI(ids)),0.5);hold off; + + diff --git a/SD-VBS/common/toolbox/toolbox_basic/common/spmtimesd.c b/SD-VBS/common/toolbox/toolbox_basic/common/spmtimesd.c new file mode 100755 index 0000000..a98dc0a --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/common/spmtimesd.c @@ -0,0 +1,141 @@ +/*================================================================ +* spmtimesd.c +* This routine computes a sparse matrix times a diagonal matrix +* whose diagonal entries are stored in a full vector. +* +* Examples: +* spmtimesd(m,d,[]) = diag(d) * m, +* spmtimesd(m,[],d) = m * diag(d) +* spmtimesd(m,d1,d2) = diag(d1) * m * diag(d2) +* m could be complex, but d is assumed real +* +* Stella X. Yu's first MEX function, Nov 9, 2001. + +% test sequence: + +m = 1000; +n = 2000; +a=sparse(rand(m,n)); +d1 = rand(m,1); +d2 = rand(n,1); +tic; b=spmtimesd(a,d1,d2); toc +tic; bb = spdiags(d1,0,m,m) * a * spdiags(d2,0,n,n); toc +e = (bb-b); +max(abs(e(:))) + +*=================================================================*/ + +# include "mex.h" + +void mexFunction( + int nargout, + mxArray *out[], + int nargin, + const mxArray *in[] +) +{ + /* declare variables */ + int i, j, k, m, n, nzmax, cmplx, xm, yn; + int *pir, *pjc, *qir, *qjc; + double *x, *y, *pr, *pi, *qr, *qi; + + /* check argument */ + if (nargin != 3) { + mexErrMsgTxt("Three input arguments required"); + } + if (nargout>1) { + mexErrMsgTxt("Too many output arguments."); + } + if (!(mxIsSparse(in[0]))) { + mexErrMsgTxt("Input argument #1 must be of type sparse"); + } + if ( mxIsSparse(in[1]) || mxIsSparse(in[2]) ) { + mexErrMsgTxt("Input argument #2 & #3 must be of type full"); + } + + /* computation starts */ + m = mxGetM(in[0]); + n = mxGetN(in[0]); + pr = mxGetPr(in[0]); + pi = mxGetPi(in[0]); + pir = mxGetIr(in[0]); + pjc = mxGetJc(in[0]); + + i = mxGetM(in[1]); + j = mxGetN(in[1]); + xm = ((i>j)? i: j); + + i = mxGetM(in[2]); + j = mxGetN(in[2]); + yn = ((i>j)? i: j); + + if ( xm>0 && xm != m) { + mexErrMsgTxt("Row multiplication dimension mismatch."); + } + if ( yn>0 && yn != n) { + mexErrMsgTxt("Column multiplication dimension mismatch."); + } + + + nzmax = mxGetNzmax(in[0]); + cmplx = (pi==NULL ? 0 : 1); + out[0] = mxCreateSparse(m,n,nzmax,cmplx); + if (out[0]==NULL) { + mexErrMsgTxt("Not enough space for the output matrix."); + } + + qr = mxGetPr(out[0]); + qi = mxGetPi(out[0]); + qir = mxGetIr(out[0]); + qjc = mxGetJc(out[0]); + + /* left multiplication */ + x = mxGetPr(in[1]); + if (yn==0) { + for (j=0; j2 + image(RGB) + axis('image') +%end diff --git a/SD-VBS/common/toolbox/toolbox_basic/disp/showmaskb.m b/SD-VBS/common/toolbox/toolbox_basic/disp/showmaskb.m new file mode 100755 index 0000000..1f67ba2 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/disp/showmaskb.m @@ -0,0 +1,20 @@ +function RGB = showmask(V,M,M2,display_flag); +% showmask(V,M); +% +% M is a nonneg. mask + +V=V-min(V(:)); +V=V/max(V(:)); +V=.25+0.75*V; %brighten things up a bit + +M=M-min(M(:)); +M=M/max(M(:)); + +H=0.6*M2+0*M; +S=min(1,M2+M); +RGB=hsv2rgb(H,S,V); + +%if nargin>2 + image(RGB) + axis('image') +%end diff --git a/SD-VBS/common/toolbox/toolbox_basic/fact/construct_w.m b/SD-VBS/common/toolbox/toolbox_basic/fact/construct_w.m new file mode 100755 index 0000000..372b4b6 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/fact/construct_w.m @@ -0,0 +1,25 @@ +function W = construct_w(centers,Ds,img_center,indexes,frames) +% +% function W = construct_w(centers,Ds,img_center,indexes,frames) +% optional: frames +% + + +points = length(indexes); +if (nargin == 4), + frames = 0.5*size(centers,2); +end + +W = zeros(2*frames,points); + +center_x = img_center(1); +center_y = img_center(2); + +for j=1:frames, + % x is centers(:,2*j-1) + % y is centers(:,2*j) + % d is Ds(:,2*j-1) + W(j,:) = (centers(indexes,2*j-1) -center_x)'./Ds(indexes,2*j-1)'; + W(j+frames,:) = (centers(indexes,2*j) -center_y)'./Ds(indexes,2*j-1)'; + % W(j+2*frames,:) = ones(1,points)./Ds(indexes,2*j-1)'; +end \ No newline at end of file diff --git a/SD-VBS/common/toolbox/toolbox_basic/fact/construct_w2.m b/SD-VBS/common/toolbox/toolbox_basic/fact/construct_w2.m new file mode 100755 index 0000000..b2939b7 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/fact/construct_w2.m @@ -0,0 +1,25 @@ +function W = construct_w2(centers,Ds,img_center,indexes,frames) +% +% function W = construct_w2(centers,Ds,img_center,indexes,frames) +% optional: frames +% + + +points = length(indexes); +if (nargin == 4), + frames = 0.5*size(centers,2); +end + +W = zeros(3*frames,points); + +center_x = img_center(1); +center_y = img_center(2); + +for j=1:frames, + % x is centers(:,2*j-1) + % y is centers(:,2*j) + % d is Ds(:,2*j-1) + W(j,:) = (centers(indexes,2*j-1) -center_x)'./Ds(indexes,2*j-1)'; + W(j+frames,:) = (centers(indexes,2*j) -center_y)'./Ds(indexes,2*j-1)'; + W(j+2*frames,:) = ones(1,points)./Ds(indexes,2*j-1)'; +end \ No newline at end of file diff --git a/SD-VBS/common/toolbox/toolbox_basic/fact/factor.m b/SD-VBS/common/toolbox/toolbox_basic/fact/factor.m new file mode 100755 index 0000000..635c29a --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/fact/factor.m @@ -0,0 +1,50 @@ +% +% Usage: +% +% [R,t,S] = factor(W) +% +% Function to factor a matrix of input data (W) into the camera +% rotation matrix (R), translation (t), and the shape matrix (S). +% Three-dimensional version. Failure of normalization results in +% empty R and S. + +function [R,t,S] = factor(W) + +pts = size(W,2); +t = W*ones(pts,1)/pts; +W = W - t*ones(1,pts); + +% Use SVD to factor W. + [a,b,c] = svd(W,0); + +smallb = b(1:3,1:3); % Since W is rank 3, b has only three meaningful values +sqrtb = sqrt(smallb); +Rhat = a(:,1:3) * sqrtb; +Shat = sqrtb * c(:,1:3)'; + +G = findG(Rhat); + +if size(G,1) == 0, +R = []; +S = []; +else + R = Rhat*G; + S = inv(G)*Shat; + + % rotation matrix that aligns the reference frame with the first camera + F = size(R,1)/2; + R1 = R(1,:); + R1 = R1/norm(R1); + R2 = R(F+1,:); + R2 = R2/norm(R2); + R3 = cross(R1,R2); + R3 = R3/norm(R3); + P = [R1; R2; R3]; + P = P'; + + R = R*P; + S = inv(P)*S; +end + + + diff --git a/SD-VBS/common/toolbox/toolbox_basic/fact/factor_test.m b/SD-VBS/common/toolbox/toolbox_basic/fact/factor_test.m new file mode 100755 index 0000000..12ceb95 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/fact/factor_test.m @@ -0,0 +1,52 @@ +% +% Usage: +% +% [R,t,S] = factor(W) +% +% Function to factor a matrix of input data (W) into the camera +% rotation matrix (R), translation (t), and the shape matrix (S). +% Three-dimensional version. Failure of normalization results in +% empty R and S. + +function [R,t,S,C,b] = factor(W) + +pts = size(W,2); +t = W*ones(pts,1)/pts; +W = W - t*ones(1,pts); + +% Use SVD to factor W. + [a,b,c] = svd(W,0); + +figure(3);plot(diag(b)) + +smallb = b(1:3,1:3); % Since W is rank 3, b has only three meaningful values +sqrtb = sqrt(smallb); +Rhat = a(:,1:3) * sqrtb; +Shat = sqrtb * c(:,1:3)'; + +[G,C] = findg1(Rhat); + +if size(G,1) == 0, +R = []; +S = []; +else + R = Rhat*G; + S = inv(G)*Shat; + + % rotation matrix that aligns the reference frame with the first camera + F = size(R,1)/2; + R1 = R(1,:); + R1 = R1/norm(R1); + R2 = R(F+1,:); + R2 = R2/norm(R2); + R3 = cross(R1,R2); + R3 = R3/norm(R3); + P = [R1; R2; R3]; + P = P'; + + R = R*P; + S = inv(P)*S; +end + + + diff --git a/SD-VBS/common/toolbox/toolbox_basic/fact/factor_test2.m b/SD-VBS/common/toolbox/toolbox_basic/fact/factor_test2.m new file mode 100755 index 0000000..3520122 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/fact/factor_test2.m @@ -0,0 +1,52 @@ +% +% Usage: +% +% [R,t,S] = factor(W) +% +% Function to factor a matrix of input data (W) into the camera +% rotation matrix (R), translation (t), and the shape matrix (S). +% Three-dimensional version. Failure of normalization results in +% empty R and S. + +function [R,t,S,C,b] = factor(W) + +pts = size(W,2); +t = W*ones(pts,1)/pts; +W = W - t*ones(1,pts); + +% Use SVD to factor W. + [a,b,c] = svd(W,0); + +figure(3);plot(diag(b)) + +smallb = b(1:3,1:3); % Since W is rank 3, b has only three meaningful values +sqrtb = sqrt(smallb); +Rhat = a(:,1:3) * sqrtb; +Shat = sqrtb * c(:,1:3)'; + +[G,C] = findg2(Rhat); + +if size(G,1) == 0, +R = []; +S = []; +else + R = Rhat*G; + S = inv(G)*Shat; + + % rotation matrix that aligns the reference frame with the first camera + F = size(R,1)/2; + R1 = R(1,:); + R1 = R1/norm(R1); + R2 = R(F+1,:); + R2 = R2/norm(R2); + R3 = cross(R1,R2); + R3 = R3/norm(R3); + P = [R1; R2; R3]; + P = P'; + + R = R*P; + S = inv(P)*S; +end + + + diff --git a/SD-VBS/common/toolbox/toolbox_basic/fact/factorizaion.tar b/SD-VBS/common/toolbox/toolbox_basic/fact/factorizaion.tar new file mode 100755 index 0000000..133cdff Binary files /dev/null and b/SD-VBS/common/toolbox/toolbox_basic/fact/factorizaion.tar differ diff --git a/SD-VBS/common/toolbox/toolbox_basic/fact/findG.m b/SD-VBS/common/toolbox/toolbox_basic/fact/findG.m new file mode 100755 index 0000000..9a6bd73 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/fact/findG.m @@ -0,0 +1,48 @@ +function G = find3G(Rhat) + +% number of frames +F = size(Rhat,1)/2; + +% Build matrix Q such that Q * v = [1,...,1,0,...,0] where v is a six +% element vector containg all six distinct elements of the Matrix C + +clear Q +for f = 1:F, + g = f + F; + h = g + F; + Q(f,:) = zt(Rhat(f,:), Rhat(f,:)); + Q(g,:) = zt(Rhat(g,:), Rhat(g,:)); + Q(h,:) = zt(Rhat(f,:), Rhat(g,:)); +end + +% Solve for v +rhs = [ones(2*F,1); zeros(F,1)]; +v = Q \ rhs; + +% C is a symmetric 3x3 matrix such that C = G * transpose(G) +C(1,1) = v(1); +C(1,2) = v(2); +C(1,3) = v(3); +C(2,2) = v(4); +C(2,3) = v(5); +C(3,3) = v(6); +C(2,1) = C(1,2); +C(3,1) = C(1,3); +C(3,2) = C(2,3); + +e = eig(C); +disp(e) + +if (any(e<= 0)), + G = []; +else + G = sqrtm(C); +end + +%neg = 0; +%if e(1) <= 0, neg = 1; end +%if e(2) <= 0, neg = 1; end +%if e(3) <= 0, neg = 1; end +%if neg == 1, G = []; +%else G = sqrtm(C); +%end diff --git a/SD-VBS/common/toolbox/toolbox_basic/fact/findg1.m b/SD-VBS/common/toolbox/toolbox_basic/fact/findg1.m new file mode 100755 index 0000000..f14ecc6 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/fact/findg1.m @@ -0,0 +1,49 @@ +function [G,C] = find3G(Rhat) + +% number of frames +F = size(Rhat,1)/2; + +% Build matrix Q such that Q * v = [1,...,1,0,...,0] where v is a six +% element vector containg all six distinct elements of the Matrix C + +clear Q +for f = 1:F, + g = f + F; + h = g + F; + Q(f,:) = zt(Rhat(f,:), Rhat(f,:)); + Q(g,:) = zt(Rhat(g,:), Rhat(g,:)); + Q(h,:) = zt(Rhat(f,:), Rhat(g,:)); +end + +% Solve for v +rhs = [ones(2*F,1); zeros(F,1)]; +v = Q \ rhs; + +% C is a symmetric 3x3 matrix such that C = G * transpose(G) +C(1,1) = v(1); +C(1,2) = v(2); +C(1,3) = v(3); +C(2,2) = v(4); +C(2,3) = v(5); +C(3,3) = v(6); +C(2,1) = C(1,2); +C(3,1) = C(1,3); +C(3,2) = C(2,3); + +e = eig(C); +disp(e) + +if (any(e<= 0)), + C = C -2*min(e)*eye(3); + G = sqrtm(C); +else + G = sqrtm(C); +end + +%neg = 0; +%if e(1) <= 0, neg = 1; end +%if e(2) <= 0, neg = 1; end +%if e(3) <= 0, neg = 1; end +%if neg == 1, G = []; +%else G = sqrtm(C); +%end diff --git a/SD-VBS/common/toolbox/toolbox_basic/fact/findg2.m b/SD-VBS/common/toolbox/toolbox_basic/fact/findg2.m new file mode 100755 index 0000000..5a84b86 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/fact/findg2.m @@ -0,0 +1,56 @@ +function [G,C] = find3G(Rhat) + +% number of frames +F = size(Rhat,1)/3; + +% Build matrix Q such that Q * v = [1,...,1,0,...,0] where v is a six +% element vector containg all six distinct elements of the Matrix C + +clear Q +for f = 1:F, + g = f + F; + h = g + F; + j = h + F; + k = j + F; + l = k + F; + Q(f,:) = zt(Rhat(f,:), Rhat(f,:)); + Q(g,:) = zt(Rhat(g,:), Rhat(g,:)); + Q(h,:) = zt(Rhat(h,:), Rhat(h,:)); + Q(j,:) = zt(Rhat(f,:), Rhat(g,:)); + Q(k,:) = zt(Rhat(f,:), Rhat(h,:)); + Q(l,:) = zt(Rhat(g,:), Rhat(h,:)); +end + +% Solve for v +rhs = [ones(3*F,1); zeros(3*F,1)]; +v = Q \ rhs; + +% C is a symmetric 3x3 matrix such that C = G * transpose(G) +C(1,1) = v(1); +C(1,2) = v(2); +C(1,3) = v(3); +C(2,2) = v(4); +C(2,3) = v(5); +C(3,3) = v(6); +C(2,1) = C(1,2); +C(3,1) = C(1,3); +C(3,2) = C(2,3); + +e = eig(C); +disp(e) + + +if (any(e<= 0)), + C = C -2*min(e)*eye(3); + G = sqrtm(C); +else + G = sqrtm(C); +end + +%neg = 0; +%if e(1) <= 0, neg = 1; end +%if e(2) <= 0, neg = 1; end +%if e(3) <= 0, neg = 1; end +%if neg == 1, G = []; +%else G = sqrtm(C); +%end diff --git a/SD-VBS/common/toolbox/toolbox_basic/fact/hotel.mat b/SD-VBS/common/toolbox/toolbox_basic/fact/hotel.mat new file mode 100755 index 0000000..61ea6c8 Binary files /dev/null and b/SD-VBS/common/toolbox/toolbox_basic/fact/hotel.mat differ diff --git a/SD-VBS/common/toolbox/toolbox_basic/fact/show_3dpoints.m b/SD-VBS/common/toolbox/toolbox_basic/fact/show_3dpoints.m new file mode 100755 index 0000000..b6edfd5 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/fact/show_3dpoints.m @@ -0,0 +1,22 @@ +function show_3dpoints(S) + + +for j=1:size(S,2), + x = S(1,j); + y = S(2,j); + z = S(3,j); + plot3(x,y,z,'*'); + hold on; + plot3([x,0],[y,0],[z,0],'r'); +% plot3([x,x],[y,y],[z,0],'r'); +% plot3([x,0],[y,y],[z,z],'r'); plot3([x,x],[y,0],[z,z],'r'); + text(x,y,z,int2str(j)) +% plot3(x,y,0,'co'); +end + +grid on +xlabel('x'); +ylabel('y'); +zlabel('z'); + +hold off \ No newline at end of file diff --git a/SD-VBS/common/toolbox/toolbox_basic/fact/show_S.m b/SD-VBS/common/toolbox/toolbox_basic/fact/show_S.m new file mode 100755 index 0000000..5828696 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/fact/show_S.m @@ -0,0 +1,17 @@ +function show_S(S,fig) + +if (nargin == 1), + figure(1); +else + figure(fig); +end + +num_points = size(S,2); + +subplot(1,2,1); plot(S(1,:),S(3,:),'cx'); axis('equal');axis('square');hold on +subplot(1,2,2); plot(S(2,:),S(3,:),'cx'); axis('equal');axis('square');hold on + +for j=1:num_points, + subplot(1,2,1);text(S(1,j),S(3,j),int2str(j));hold off + subplot(1,2,2);text(S(2,j),S(3,j),int2str(j));hold off +end diff --git a/SD-VBS/common/toolbox/toolbox_basic/fact/show_t.m b/SD-VBS/common/toolbox/toolbox_basic/fact/show_t.m new file mode 100755 index 0000000..b475c76 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/fact/show_t.m @@ -0,0 +1,10 @@ +function show_t(t) + +frames = 0.5*length(t); + +ts = reshape(t,frames,2); + +plot(ts(:,1),ts(:,2)); +hold on +plot(ts(:,1),ts(:,2),'rx'); +hold off; diff --git a/SD-VBS/common/toolbox/toolbox_basic/fact/show_t3.m b/SD-VBS/common/toolbox/toolbox_basic/fact/show_t3.m new file mode 100755 index 0000000..2766061 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/fact/show_t3.m @@ -0,0 +1,10 @@ +function show_t(t) + +frames = length(t)/3; + +ts = reshape(t,frames,3); + +plot3(ts(:,1),ts(:,2),ts(:,3)); +hold on +plot3(ts(:,1),ts(:,2),ts(:,3),'rx'); +hold off; diff --git a/SD-VBS/common/toolbox/toolbox_basic/fact/zt.m b/SD-VBS/common/toolbox/toolbox_basic/fact/zt.m new file mode 100755 index 0000000..3f88d21 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/fact/zt.m @@ -0,0 +1,6 @@ +% the z' operator described in the paper (returns a row vector) + +function v = zt(a, b) + +v = [ a(1)*b(1), a(1)*b(2)+a(2)*b(1), a(1)*b(3)+a(3)*b(1), ... + a(2)*b(2), a(2)*b(3)+a(3)*b(2), a(3)*b(3) ]; diff --git a/SD-VBS/common/toolbox/toolbox_basic/filter/91048.jpg b/SD-VBS/common/toolbox/toolbox_basic/filter/91048.jpg new file mode 100755 index 0000000..6b2313b Binary files /dev/null and b/SD-VBS/common/toolbox/toolbox_basic/filter/91048.jpg differ diff --git a/SD-VBS/common/toolbox/toolbox_basic/filter/bar2d.m b/SD-VBS/common/toolbox/toolbox_basic/filter/bar2d.m new file mode 100755 index 0000000..76fa819 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/filter/bar2d.m @@ -0,0 +1,16 @@ +function kernel = bar2d(sigx,sigy,siz,angle) + +X = -siz:.1:siz; +G = exp(-0.5*X.^2/sigx^2); + +DGG = (1/sigy^2) * ((X/sigy).^2-1) .* exp(- (X/sigy).^2/2); +%DGG = (X.^2/(sqrt(2*pi)*sigy^5) - 1/(sqrt(2*pi)*sigy^2)) .* ... +% exp(-0.5*X.^2/sigy^2); + +K = G'*DGG; +K = rotate_J(angle,K); + +K = imresize(K,0.1); +K = K-mean(mean(K)); + +kernel = K; \ No newline at end of file diff --git a/SD-VBS/common/toolbox/toolbox_basic/filter/barrot.m b/SD-VBS/common/toolbox/toolbox_basic/filter/barrot.m new file mode 100755 index 0000000..bd7676e --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/filter/barrot.m @@ -0,0 +1,22 @@ +img1 = gifread('color010.gif'); +img1 = img1(220:350,1:200); +img2 = gifread('color-avg.gif'); +img2 = img2(220:350,1:200); + +sigx = 3; +sigy = 3; +siz = 8; +angles = 0:19:179; + +[Imag1,Iangle1] = brute_force_angle(img1,sigx,sigy,siz,angles); +[Imag2,Iangle2] = brute_force_angle(img2,sigx,sigy,siz,angles); + +tresh = max(max(Imag1))*0.1 +D = angle_diff(Imag1,Iangle1,Imag2,Iangle2,tresh); +subplot(2,2,1); imagesc(Iangle1*180/pi); colorbar; +subplot(2,2,2); imagesc(Iangle2*180/pi); colorbar; +subplot(2,2,3); imagesc(D*180/pi); colorbar; +subplot(2,2,4); imagesc(Imag1); colorbar; +colormap(jet) + + diff --git a/SD-VBS/common/toolbox/toolbox_basic/filter/bars.m b/SD-VBS/common/toolbox/toolbox_basic/filter/bars.m new file mode 100755 index 0000000..77eccea --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/filter/bars.m @@ -0,0 +1,39 @@ +function [filt] = bars(X,Y,ks); +%FIL1 the first filter to use has the following specifications: +% +% real part: 2nd derivative of gaussian along Y +% normal gaussian along X +% This filter is elongated along the X direction +% imag part: hilbert transform of the real part +% +% [filt] = fil1(X,Y,ks); +% X,Y : index matrix obtained by meshgrid +% ks : kernel size +% filt : the output kernel +% + +%% +%% (c) Thomas Leung +%% California Institute of Technology +%% Feb 27, 1994. +%% + +if(nargin == 2) + ks = 17; +end + +sigmay = 2.4 * ks / 17; +sigmax = 3 * sigmay; + +fxr = exp(-(X/sigmax).^2/2); +fyr = (1/sigmay^2) * ((Y/sigmay).^2-1) .* exp(- (Y/sigmay).^2/2); +nrm = 1/(sigmax*sigmay*2*pi); + +% real part of filter +fr = nrm * fxr .* fyr; + +% imag part of filter +filt = hilbert(fr); + + +return; diff --git a/SD-VBS/common/toolbox/toolbox_basic/filter/clip_image.m b/SD-VBS/common/toolbox/toolbox_basic/filter/clip_image.m new file mode 100755 index 0000000..bf7b50c --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/filter/clip_image.m @@ -0,0 +1,6 @@ +function J = clip_image(I,w) + +[size_y,size_x] = size(I); + +J = I(w+1:size_y-w,w+1:size_x-w); + diff --git a/SD-VBS/common/toolbox/toolbox_basic/filter/compute_J_simple.m b/SD-VBS/common/toolbox/toolbox_basic/filter/compute_J_simple.m new file mode 100755 index 0000000..e790601 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/filter/compute_J_simple.m @@ -0,0 +1,50 @@ +function J = compute_J(I,A,D,base) +%% function J = compute_J(I,A,D) +% + +if nargin == 3, + base = -1; +end + +[size_y,size_x] = size(I); +[center_x,center_y] = find_center(size_x,size_y); + +add_x = round(size_x*0.45); +add_y = round(size_y*0.45); +big_I = base*ones(size_y+2*add_y,size_x+2*add_x); + +big_I(add_y+1:add_y+size_y,add_x+1:add_x+size_x) = I; + +center_x = add_x+ center_x; +center_y = add_y+ center_y; +[size_y,size_x] = size(big_I); + +%a = angle * pi/180; +%A = [cos(a),-sin(a);sin(a),cos(a)]; + +[XX,YY] = meshgrid(1:size_x,1:size_y); + +x = reshape(XX,size_x*size_y,1); +y = reshape(YY,size_x*size_y,1); +index(:,1) = x-center_x; + +%index(:,2) = (size_y+1) - y; +index(:,2) = y-center_y; + +position_new = A*index'; +position_new(1,:) = position_new(1,:)+D(1)+center_x; +position_new(2,:) = position_new(2,:)+D(2)+center_y; +%position_new(2,:) = (size_y+1) - position_new(2,:); + +position_new_x = reshape(position_new(1,:),size_y,size_x); +position_new_y = reshape(position_new(2,:),size_y,size_x); + +J = m_interp4(big_I,position_new_x,position_new_y); + + +[size_y,size_x] = size(I); +J = J(add_y+1:add_y+size_y,add_x+1:add_x+size_x); + + + + diff --git a/SD-VBS/common/toolbox/toolbox_basic/filter/compute_angle.m b/SD-VBS/common/toolbox/toolbox_basic/filter/compute_angle.m new file mode 100755 index 0000000..7a995af --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/filter/compute_angle.m @@ -0,0 +1,18 @@ +function [angle,mag,c2,c3] = compute_angle(I) + +[g,ga,gb,gc] = compute_g2(I,0); +[h,ha,hb,hc,hd] = compute_h2(I,0); + +c2 = 0.5*(ga.^2 - gc.^2) + 0.46875*(ha.^2 - hd.^2) +... + 0.28125*(hb.^2 - hc.^2) + 0.1875*(ha.*hc - hb.*hd); + +c3 = -ga.*gb - gb.*gc - 0.9375*(hc.*hd + ha.*hb) -... + 1.6875*hb.*hc - 0.1875*ha.*hd; + +[angle,mag] = cart2pol(-c2,-c3); + +%angle = angle/2+pi/2; +%angle = (angle>pi).*(angle-2*pi) + (angle<=pi).*angle; + +angle = angle/2; +mag = sqrt(mag); \ No newline at end of file diff --git a/SD-VBS/common/toolbox/toolbox_basic/filter/compute_filter_fft.m b/SD-VBS/common/toolbox/toolbox_basic/filter/compute_filter_fft.m new file mode 100755 index 0000000..359c6ba --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/filter/compute_filter_fft.m @@ -0,0 +1,84 @@ +function [filter_output,filters] = compute_filter_fft(I,sig,r,sz,num_ori); +% +% +% + +ori_incr=180/num_ori; +ori_offset=ori_incr/2; % helps with equalizing quantiz. error across filter set + +as = ori_offset:ori_incr:180+ori_offset-ori_incr; + +filter_output = []; +filters = []; + +wsz = 2*round(sz(end)) + 1; +M1 = wsz;M2 = wsz; + +%%%%% prepare FFT of image %%%%%%%%%%%%% + +[N1,N2]=size(I); +tmp=zeros(size(I)+[M1-1 M2-1]); +tmp(1:N1,1:N2)=I; +IF=fft2(tmp); + + +%%%%%%%%%% filtering stage %%%%%%%%%%% +if size(sig,2)== 1, + + for j = 1:length(as), + fprintf('.'); + angle = as(j); + + g = mdoog2(sig,r,angle,round(sz)); + + g = g - mean(reshape(g,prod(size(g)),1)); + + g = g/sum(sum(abs(g))); + + filters(:,:,j) = g; + + gF = fft2(g,N1+M1-1,N2+M2-1); + IgF = IF.*gF; + Ig = real(ifft2(IgF)); + Ig = Ig(ceil((M1+1)/2):ceil((M1+1)/2)+N1-1,ceil((M2+1)/2):ceil((M2+1)/2)+N2-1); + + %c = conv2(I,g,'valid'); + + filter_output(:,:,j) = Ig; + end +else + + % there are multiple scales + sigs = sig; + szs = sz; + for k = 1:size(sigs,2), + sig = sigs(k); + sz = szs(end); + fprintf('%d',k); + for j = 1:length(as), + fprintf('.'); + angle = as(j); + + g = mdoog2(sig,r,angle,round(sz)); + g = g - mean(reshape(g,prod(size(g)),1)); + g = g/sum(sum(abs(g))); + + gF = fft2(g,N1+M1-1,N2+M2-1); + IgF = IF.*gF; + Ig = real(ifft2(IgF)); + Ig = Ig(ceil((M1+1)/2):ceil((M1+1)/2)+N1-1,ceil((M2+1)/2):ceil((M2+1)/2)+N2-1); + + %c = conv2(I,g,'valid'); + %c = conv2(I,g,'same'); + + filter_output(:,:,j,k) = Ig; + filters(:,:,j,k) = g; + end + + + end + +end + +fprintf('\n'); + diff --git a/SD-VBS/common/toolbox/toolbox_basic/filter/compute_g2.m b/SD-VBS/common/toolbox/toolbox_basic/filter/compute_g2.m new file mode 100755 index 0000000..ac27d00 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/filter/compute_g2.m @@ -0,0 +1,23 @@ +function [g,ga,gb,gc] = compute_g2(I,angle) + +if (nargin == 1), + angle = 0; +end + +f1 = [0.0094 0.1148 0.3964 -0.0601 -0.9213 -0.0601 0.3964 0.1148 0.0094]; +f2 = [0.0008 0.0176 0.166 0.6383 1.0 0.6383 0.166 0.0176 0.0008]; +f3 = [-0.0028 -0.048 -0.302 -0.5806 0 0.5806 0.302 0.048 0.0028]; + +%ga = conv2(conv2(I,f2,'same'),f1','same'); +%gb = conv2(conv2(I,f3,'same'),f3','same'); +%gc = conv2(conv2(I,f1,'same'),f2','same'); + +ga = conv2(conv2(I,f1,'same'),f2','same'); +gb = conv2(conv2(I,f3,'same'),f3','same'); +gc = conv2(conv2(I,f2,'same'),f1','same'); + +ka = cos(angle)^2; +kb = -2*cos(angle)*sin(angle); +kc = sin(angle)^2; + +g = ka*ga + kb*gb + kc*gc; diff --git a/SD-VBS/common/toolbox/toolbox_basic/filter/compute_h2.m b/SD-VBS/common/toolbox/toolbox_basic/filter/compute_h2.m new file mode 100755 index 0000000..e4cdcfb --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/filter/compute_h2.m @@ -0,0 +1,27 @@ +function [h,ha,hb,hc,hd] = compute_h2(I,angle) + +if (nargin == 1), + angle = 0; +end + +f1 = [0.0098 0.0618 -0.0998 -0.7551 0 0.7551 0.0998 -0.0618 -0.0098]; +f2 = [ 0.0008 0.0176 0.166 0.6383 1 0.6383 0.166 0.0176 0.0008]; +f3 = -[-0.002 -0.0354 -0.2225 -0.4277 0 0.4277 0.2225 0.0354 0.002]; +f4 = [0.0048 0.0566 0.1695 -0.1889 -0.7349 -0.1889 0.1695 0.0566 0.0048]; + +%ha = conv2(conv2(I,f2,'same'),f1','same'); +%hb = conv2(conv2(I,f3,'same'),f4','same'); +%hc = conv2(conv2(I,f4,'same'),f3','same'); +%hd = conv2(conv2(I,f1,'same'),f2','same'); + +ha = conv2(conv2(I,f1,'same'),f2','same'); +hb = conv2(conv2(I,f4,'same'),f3','same'); +hc = conv2(conv2(I,f3,'same'),f4','same'); +hd = conv2(conv2(I,f2,'same'),f1','same'); + +ka = cos(angle)^3; +kb = -3*cos(angle)^2*sin(angle); +kc = 3*cos(angle)*sin(angle)^2; +kd = -sin(angle)^3; + +h = ka*ha + kb*hb + kc*hc + kd*hd; diff --git a/SD-VBS/common/toolbox/toolbox_basic/filter/compute_ofilter_fft.m b/SD-VBS/common/toolbox/toolbox_basic/filter/compute_ofilter_fft.m new file mode 100755 index 0000000..41989ed --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/filter/compute_ofilter_fft.m @@ -0,0 +1,88 @@ +function [filter_output,filters] = compute_odd_filter_fft(I,sig,r,sz,num_ori); +% +% computes the filter response of I to the set of odd symmetric filters +% +% sig = scale(sigma) for the filters +% r = enlongation factor +% sz = the radius of the filters +% num_ori = number of orientations +% + +ori_incr=180/num_ori; +ori_offset=ori_incr/2; % helps with equalizing quantiz. error across filter set + +as = ori_offset:ori_incr:180+ori_offset-ori_incr; + +filter_output = zeros(size(I,1),size(I,2),num_ori,length(sig)); +filters = []; + +wsz = 2*round(sz(end)) + 1; +M1 = wsz;M2 = wsz; + +%%%%% prepare FFT of image %%%%%%%%%%%%% + +[N1,N2]=size(I); +tmp=zeros(size(I)+[M1-1 M2-1]); +tmp(1:N1,1:N2)=I; +IF=fft2(tmp); + + +%%%%%%%%%% filtering stage %%%%%%%%%%% +if size(sig,2)== 1, + + for j = 1:length(as), + fprintf('.'); + angle = as(j); + + g = mk_odd_filter(sig,r,angle,round(sz)); + + g = g - mean(reshape(g,prod(size(g)),1)); + + g = g/sum(sum(abs(g))); + + filters(:,:,j,1) = g; + + gF = fft2(g,N1+M1-1,N2+M2-1); + IgF = IF.*gF; + Ig = real(ifft2(IgF)); + Ig = Ig(ceil((M1+1)/2):ceil((M1+1)/2)+N1-1,ceil((M2+1)/2):ceil((M2+1)/2)+N2-1); + + %c = conv2(I,g,'valid'); + + filter_output(:,:,j,1) = Ig; + end +else + + % there are multiple scales + sigs = sig; + szs = sz; + for k = 1:size(sigs,2), + sig = sigs(k); + sz = szs(end); + fprintf('%d',k); + + for j = 1:length(as), + fprintf('.'); + angle = as(j); + + g = mk_odd_filter(sig,r,angle,round(sz)); + g = g - mean(reshape(g,prod(size(g)),1)); + g = g/sum(sum(abs(g))); + + gF = fft2(g,N1+M1-1,N2+M2-1); + IgF = IF.*gF; + Ig = real(ifft2(IgF)); + Ig = Ig(ceil((M1+1)/2):ceil((M1+1)/2)+N1-1,ceil((M2+1)/2):ceil((M2+1)/2)+N2-1); + + %c = conv2(I,g,'valid'); + %c = conv2(I,g,'same'); + + filter_output(:,:,j,k) = Ig; + filters(:,:,j,k) = g; + end + end + +end + +fprintf('\n'); + diff --git a/SD-VBS/common/toolbox/toolbox_basic/filter/dgauss.m b/SD-VBS/common/toolbox/toolbox_basic/filter/dgauss.m new file mode 100755 index 0000000..207e781 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/filter/dgauss.m @@ -0,0 +1,16 @@ +function dg = dgauss(sig) +% first derivative of N(sig) +% cutoff after 1% of max + + i = 1; + max = 0; + dgi = max; + dg = [dgi]; + while dgi >= 0.01*max + dgi = i / (sqrt(2*pi) * sig^3) * exp(-0.5*i^2/sig^2); + dg = [dgi dg -dgi]; + i = i + 1; + if dgi > max + max = dgi; + end + end; \ No newline at end of file diff --git a/SD-VBS/common/toolbox/toolbox_basic/filter/dog1.m b/SD-VBS/common/toolbox/toolbox_basic/filter/dog1.m new file mode 100755 index 0000000..e9f64e6 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/filter/dog1.m @@ -0,0 +1,28 @@ +function G=dog1(sig,N); +% G=dog1(sig,N); + +% by Serge Belongie + +no_pts=N; % no. of points in x,y grid + +[x,y]=meshgrid(-(N/2)+1/2:(N/2)-1/2,-(N/2)+1/2:(N/2)-1/2); + +sigi=0.71*sig; +sigo=1.14*sig; +Ci=diag([sigi,sigi]); +Co=diag([sigo,sigo]); + +X=[x(:) y(:)]; + +Ga=gaussian(X,[0 0]',Ci); +Ga=reshape(Ga,N,N); +Gb=gaussian(X,[0 0]',Co); +Gb=reshape(Gb,N,N); + +a=1; +b=-1; + +G = a*Ga + b*Gb; + +G=G-mean(G(:)); + diff --git a/SD-VBS/common/toolbox/toolbox_basic/filter/dog2.m b/SD-VBS/common/toolbox/toolbox_basic/filter/dog2.m new file mode 100755 index 0000000..8446198 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/filter/dog2.m @@ -0,0 +1,31 @@ +function G=dog2(sig,N); +% G=dog2(sig,N); + +% by Serge Belongie + +no_pts=N; % no. of points in x,y grid + +[x,y]=meshgrid(-(N/2)+1/2:(N/2)-1/2,-(N/2)+1/2:(N/2)-1/2); + +sigi=0.62*sig; +sigo=1.6*sig; +C=diag([sig,sig]); +Ci=diag([sigi,sigi]); +Co=diag([sigo,sigo]); + +X=[x(:) y(:)]; + +Ga=gaussian(X,[0 0]',Ci); +Ga=reshape(Ga,N,N); +Gb=gaussian(X,[0 0]',C); +Gb=reshape(Gb,N,N); +Gc=gaussian(X,[0 0]',Co); +Gc=reshape(Gc,N,N); + +a=-1; +b=2; +c=-1; + +G = a*Ga + b*Gb + c*Gc; + +G=G-mean(G(:)); diff --git a/SD-VBS/common/toolbox/toolbox_basic/filter/doog1.m b/SD-VBS/common/toolbox/toolbox_basic/filter/doog1.m new file mode 100755 index 0000000..dd8e87b --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/filter/doog1.m @@ -0,0 +1,32 @@ +function H=doog1(sig,r,th,N); +% H=doog1(sig,r,th,N); + + +% by Serge Belongie + +no_pts=N; % no. of points in x,y grid + +[x,y]=meshgrid(-(N/2)+1/2:(N/2)-1/2,-(N/2)+1/2:(N/2)-1/2); + +phi=pi*th/180; +sigy=sig; +sigx=r*sig; +R=[cos(phi) -sin(phi); sin(phi) cos(phi)]; +C=R*diag([sigx,sigy])*R'; + +X=[x(:) y(:)]; + +Gb=gaussian(X,[0 0]',C); +Gb=reshape(Gb,N,N); + +m=R*[0 sig]'; + +a=1; +b=-1; + +% make odd-symmetric filter +Ga=gaussian(X,m/2,C); +Ga=reshape(Ga,N,N); +Gb=rot90(Ga,2); +H=a*Ga+b*Gb; + diff --git a/SD-VBS/common/toolbox/toolbox_basic/filter/doog2.m b/SD-VBS/common/toolbox/toolbox_basic/filter/doog2.m new file mode 100755 index 0000000..a0511cb --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/filter/doog2.m @@ -0,0 +1,38 @@ +function G=doog2(sig,r,th,N); +% G=doog2(sig,r,th,N); +% Make difference of offset gaussians kernel +% theta is in degrees +% (see Malik & Perona, J. Opt. Soc. Amer., 1990) +% +% Example: +% >> imagesc(doog2(1,12,0,64,1)) +% >> colormap(gray) + +% by Serge Belongie + +no_pts=N; % no. of points in x,y grid + +[x,y]=meshgrid(-(N/2)+1/2:(N/2)-1/2,-(N/2)+1/2:(N/2)-1/2); + +phi=pi*th/180; +sigy=sig; +sigx=r*sig; +R=[cos(phi) -sin(phi); sin(phi) cos(phi)]; +C=R*diag([sigx,sigy])*R'; + +X=[x(:) y(:)]; + +Gb=gaussian(X,[0 0]',C); +Gb=reshape(Gb,N,N); + +m=R*[0 sig]'; +Ga=gaussian(X,m,C); +Ga=reshape(Ga,N,N); +Gc=rot90(Ga,2); + +a=-1; +b=2; +c=-1; + +G = a*Ga + b*Gb + c*Gc; + diff --git a/SD-VBS/common/toolbox/toolbox_basic/filter/fft_filt.m b/SD-VBS/common/toolbox/toolbox_basic/filter/fft_filt.m new file mode 100755 index 0000000..25fa5f9 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/filter/fft_filt.m @@ -0,0 +1,82 @@ +% script for fft-based filtering + +% set up filterbank +make_filterbank + +% prepare FFT of image for filtering +[N1,N2]=size(V); +I=zeros(size(V)+[M1-1 M2-1]); +I(1:N1,1:N2)=V; +IF=fft2(I); +FI=zeros(N1,N2,total_num_filt); + +% apply filters +for n=1:total_num_filt + disp(n) + f=rot90(FB(:,:,n),2); + fF=fft2(f,N1+M1-1,N2+M2-1); + IfF=IF.*fF; + If=real(ifft2(IfF)); + If=If(ceil((M1+1)/2):ceil((M1+1)/2)+N1-1,ceil((M2+1)/2):ceil((M2+1)/2)+N2-1); + FI(:,:,n)=If; +% im(If) +% drawnow +end + +%%%% end of filtering part; the remainder is for reconstruction & analysis +break + + +% use pseudoinverse to reconstruct image from filter projections +fbv=reshape(FB,M1*M2,total_num_filt)'; +fbi=pinv(fbv); + +% find principal components +T=reshape(FI,N1*N2,total_num_filt)'; +C=T*T'; +[U,S,junk]=svd(C); +s=diag(S); + +% synthesize using some eigenvectors +synth=fbi*U; +k=ceil(sqrt(total_num_filt)); +for n=1:total_num_filt + subplot(k,k,n) + im(reshape(synth(:,n),M1,M2)); + title(num2str(s(n))) + drawnow +end + +% synthesize at a point by clicking on coordinates +figure(1) +im(V) +[x,y]=ginput(1); +x=round(x); +y=round(y); +u=squeeze(FI(y,x,:)); +synth=fbi*u; +synth=reshape(synth,M1,M2); +figure(2) +subplot(1,2,1) +im(V) +axis([x-M2/2 x+M2/2 y-M1/2 y+M1/2]) +subplot(1,2,2) +im(synth) +title(num2str(max(synth(:)))); + +figure(3) +plot(u,'o-') + +% show pseudoinverse filterbank +if 0 +k=ceil(sqrt(total_num_filt)); +for n=1:total_num_filt + subplot(k,k,n) + im(reshape(fbi(:,n),M1,M2)); + axis('off') + drawnow +end +end + + + diff --git a/SD-VBS/common/toolbox/toolbox_basic/filter/fft_filt_2.m b/SD-VBS/common/toolbox/toolbox_basic/filter/fft_filt_2.m new file mode 100755 index 0000000..9c84e96 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/filter/fft_filt_2.m @@ -0,0 +1,29 @@ +function FI=fft_filt_2(V,FB,sf); +% FI=fft_filt_2(V,FB,sf); +% fft-based filtering +% requires image to be called "V" +% and filters to be in FB +% sf is the subsampling factor +% +% FI is the result + +[M1,M2,N3]=size(FB); +% prepare FFT of image for filtering +[N1,N2]=size(V); +I=zeros(size(V)+[M1-1 M2-1]); +I(1:N1,1:N2)=V; +N1s=length(1:sf:N1); +N2s=length(1:sf:N2); +IF=fft2(I); +FI=zeros(N1s,N2s,N3); + +% apply filters +for n=1:N3; + f=rot90(FB(:,:,n),2); + fF=fft2(f,N1+M1-1,N2+M2-1); + IfF=IF.*fF; + If=real(ifft2(IfF)); + If=If(ceil((M1+1)/2):ceil((M1+1)/2)+N1-1,ceil((M2+1)/2):ceil((M2+1)/2)+N2-1); + FI(:,:,n)=If(1:sf:N1,1:sf:N2); +end + diff --git a/SD-VBS/common/toolbox/toolbox_basic/filter/filter_bank_jshi.tar b/SD-VBS/common/toolbox/toolbox_basic/filter/filter_bank_jshi.tar new file mode 100755 index 0000000..b43b49c Binary files /dev/null and b/SD-VBS/common/toolbox/toolbox_basic/filter/filter_bank_jshi.tar differ diff --git a/SD-VBS/common/toolbox/toolbox_basic/filter/gauss.m b/SD-VBS/common/toolbox/toolbox_basic/filter/gauss.m new file mode 100755 index 0000000..f0403ed --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/filter/gauss.m @@ -0,0 +1,16 @@ +function dg = gauss(sig) +% first derivative of N(sig) +% cutoff after 1% of max + + i = 1; + max = 0; + dgi = max; + dg = [1/ (sqrt(2*pi) * sig) ]; + while dgi >= 0.01*max + dgi = 1/ (sqrt(2*pi) * sig) * exp(-0.5*i^2/sig^2); + dg = [dgi dg dgi]; + i = i + 1; + if dgi > max + max = dgi; + end + end; \ No newline at end of file diff --git a/SD-VBS/common/toolbox/toolbox_basic/filter/gaussian.m b/SD-VBS/common/toolbox/toolbox_basic/filter/gaussian.m new file mode 100755 index 0000000..509b129 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/filter/gaussian.m @@ -0,0 +1,31 @@ +function p=gaussian(x,m,C); +% p=gaussian(x,m,C); +% +% Evaluate the multi-variate density with mean vector m and covariance +% matrix C for the input vector x. +% +% p=gaussian(X,m,C); +% +% Vectorized version: Here X is a matrix of column vectors, and p is +% a vector of probabilities for each vector. + +d=length(m); + +if size(x,1)~=d + x=x'; +end +N=size(x,2); + +detC = det(C); +if rcond(C)threshold); + + + + + + + + diff --git a/SD-VBS/common/toolbox/toolbox_basic/filter/get_diff_free.m b/SD-VBS/common/toolbox/toolbox_basic/filter/get_diff_free.m new file mode 100755 index 0000000..f020fab --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/filter/get_diff_free.m @@ -0,0 +1,8 @@ +function [diff,corr,mag,angle] = get_diff_free(I,J) + +[angle,mag,c2,c3] = compute_angle(I); +[angleJ,magJ] = compute_angle(J); + +corr = cos(angle).*cos(angleJ) + sin(angle).*sin(angleJ); +threshold = 0.075*max(max(mag(5:size(mag,1)-5,5:size(mag,2)-5))); +diff = (abs(corr)<0.9).*(mag>threshold); \ No newline at end of file diff --git a/SD-VBS/common/toolbox/toolbox_basic/filter/grad1.m b/SD-VBS/common/toolbox/toolbox_basic/filter/grad1.m new file mode 100755 index 0000000..eca34db --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/filter/grad1.m @@ -0,0 +1,11 @@ +function [gx,gy] = grad2(I,ratio) +% +% + +kern = dgauss(ratio);kern = kern/sum(abs(kern)); +gkern = gauss(ratio);gkern = gkern/sum(abs(kern)); + +gx = conv2(I,kern,'same'); +gx = conv2(gx,gkern','same'); + +gy = conv2(conv2(I,kern','same'),gkern,'same'); diff --git a/SD-VBS/common/toolbox/toolbox_basic/filter/grad2.m b/SD-VBS/common/toolbox/toolbox_basic/filter/grad2.m new file mode 100755 index 0000000..ea4ec0e --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/filter/grad2.m @@ -0,0 +1,11 @@ +function [gx,gy] = grad2(I,ratio) +% +% + +ddgauss = gradient(dgauss(ratio));ddgauss = ddgauss/sum(abs(ddgauss)); +gkern = gauss(ratio); gkern = gkern/sum(abs(gkern)); + +gx = conv2(I,ddgauss,'same'); +gx = conv2(gx,gkern','same'); + +gy = conv2(conv2(I,ddgauss','same'),gkern,'same'); diff --git a/SD-VBS/common/toolbox/toolbox_basic/filter/m_interp4.m b/SD-VBS/common/toolbox/toolbox_basic/filter/m_interp4.m new file mode 100755 index 0000000..314f140 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/filter/m_interp4.m @@ -0,0 +1,49 @@ +function [F,mask] = m_interp4(z,s,t) +%INTERP4 2-D bilinear data interpolation. +% ZI = INTERP4(Z,XI,YI) assumes X = 1:N and Y = 1:M, where +% [M,N] = SIZE(Z). +% +% Copyright (c) 1984-93 by The MathWorks, Inc. +% Clay M. Thompson 4-26-91, revised 7-3-91, 3-22-93 by CMT. +% +% modified to + + +[nrows,ncols] = size(z); + + +if any(size(z)<[3 3]), error('Z must be at least 3-by-3.'); end +if size(s)~=size(t), error('XI and YI must be the same size.'); end + +% Check for out of range values of s and set to 1 +sout = find((s<1)|(s>ncols)); +if length(sout)>0, s(sout) = ones(size(sout)); end + +% Check for out of range values of t and set to 1 +tout = find((t<1)|(t>nrows)); +if length(tout)>0, t(tout) = ones(size(tout)); end + +% Matrix element indexing +ndx = floor(t)+floor(s-1)*nrows; + +% Compute intepolation parameters, check for boundary value. +d = find(s==ncols); +s(:) = (s - floor(s)); +if length(d)>0, s(d) = s(d)+1; ndx(d) = ndx(d)-nrows; end + +% Compute intepolation parameters, check for boundary value. +d = find(t==nrows); +t(:) = (t - floor(t)); +if length(d)>0, t(d) = t(d)+1; ndx(d) = ndx(d)-1; end +d = []; + +% Now interpolate, reuse u and v to save memory. +F = ( z(ndx).*(1-t) + z(ndx+1).*t ).*(1-s) + ... + ( z(ndx+nrows).*(1-t) + z(ndx+(nrows+1)).*t ).*s; + +mask = ones(size(z)); + +% Now set out of range values to zeros. +if length(sout)>0, F(sout) = zeros(size(sout));mask(sout)=zeros(size(sout));end +if length(tout)>0, F(tout) = zeros(size(tout));mask(tout)=zeros(size(tout));end + diff --git a/SD-VBS/common/toolbox/toolbox_basic/filter/make_filterbank.m b/SD-VBS/common/toolbox/toolbox_basic/filter/make_filterbank.m new file mode 100755 index 0000000..2ff15d2 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/filter/make_filterbank.m @@ -0,0 +1,63 @@ +function FB = make_filterbank(num_ori,num_scale,wsz) +% +% F = make_filterbank(num_ori,num_scale,wsz) +% + + +% definine filterbank +%num_ori=6; +%num_scale=3; + +M1=wsz; % size in pixels +M2=M1; + +ori_incr=180/num_ori; +ori_offset=ori_incr/2; % helps with equalizing quantiz. error across filter set + +FBdoog1=zeros(M1,M2,num_scale,num_ori); +FBdoog2=zeros(M1,M2,num_scale,num_ori); +FBdog1=zeros(M1,M2,num_scale); +FBdog2=zeros(M1,M2,num_scale); + +% elongated filter set +counter = 1; +filter_scale = 1.0; +filter_scale_step = sqrt(2); + +for m=1:num_scale + f=dog1(filter_scale,M1); + FBdog1(:,:,m)=f; + f=dog2(filter_scale,M1); + FBdog2(:,:,m)=f; + counter=counter+1; + for n=1:num_ori + % r=12 here is equivalent to Malik's r=3; + f=doog2(filter_scale,6,ori_offset+(n-1)*ori_incr,M1); + FBdoog2(:,:,m,n)=f; + f=doog1(filter_scale,6,ori_offset+(n-1)*ori_incr,M1); + FBdoog1(:,:,m,n)=f; + end + filter_scale = filter_scale * filter_scale_step; +end + +FB=cat(3,3*FBdog1,4.15*FBdog2,2*reshape(FBdoog1,M1,M2,num_scale*num_ori),2*reshape(FBdoog2,M1,M2,num_scale*num_ori)); +total_num_filt=size(FB,3); + +nb = size(FB,3); +for j=1:nb, + F = FB(:,:,j); + a = sum(sum(abs(F))); + FB(:,:,j) = FB(:,:,j)/a; +end + + +if 0 +k=ceil(sqrt(total_num_filt)); +for n=1:total_num_filt + subplot(k,k,n) + im(FB(:,:,n)); + axis('off') + drawnow +end +end + diff --git a/SD-VBS/common/toolbox/toolbox_basic/filter/make_filterbank_23.m b/SD-VBS/common/toolbox/toolbox_basic/filter/make_filterbank_23.m new file mode 100755 index 0000000..f9fcaa9 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/filter/make_filterbank_23.m @@ -0,0 +1,40 @@ +function [FB,M1,M2,N3]=make_filterbank_23; +% multi-scale even and odd filters + +M1=31; % size in pixels +M2=M1; +num_ori=6; +num_scales=3; +num_phases=2; +N3=num_ori*num_scales*num_phases; +FB=zeros(M1,M2,N3); + +counter=1; + +for m=1:num_scales + for n=1:num_ori + [F1,F2]=quadpair(sqrt(2)^m,3,180*(n-1)/num_ori,M1); + FB(:,:,counter)=F1; + counter=counter+1; + FB(:,:,counter)=F2; + counter=counter+1; + end +end + +FB=cat(3,FB,dog2(1,M1),dog2(sqrt(2),M1),dog2(2,M1),dog2(2*sqrt(2),M1)); + +N3=size(FB,3); + +% stuff for visualizing spectra of filters: +if 0 +FBF=zeros(size(FB)); + +for n=1:36 + FBF(:,:,n)=abs(fftshift(fft2(FB(:,:,n)))); +end + +montage2(FBF) + +im(sum(FBF,3)) + +end diff --git a/SD-VBS/common/toolbox/toolbox_basic/filter/make_filterbank_even.m b/SD-VBS/common/toolbox/toolbox_basic/filter/make_filterbank_even.m new file mode 100755 index 0000000..8c8d802 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/filter/make_filterbank_even.m @@ -0,0 +1,40 @@ +function FB = make_filterbank(num_ori,filter_scales,wsz) +% +% F = make_filterbank(num_ori,num_scale,wsz) +% + + +% definine filterbank +%num_ori=6; +%num_scale=3; + +num_scale = length(filter_scales); + +M1=wsz; % size in pixels +M2=M1; + +ori_incr=180/num_ori; +ori_offset=ori_incr/2; % helps with equalizing quantiz. error across filter set + +FB=zeros(M1,M2,num_ori,num_scale); + +% elongated filter set +counter = 1; + +for m=1:num_scale + for n=1:num_ori + % r=12 here is equivalent to Malik's r=3; + f=doog2(filter_scales(m),6,ori_offset+(n-1)*ori_incr,M1); + FB(:,:,n,m)=f; + end +end + +FB=reshape(FB,M1,M2,num_scale*num_ori); +total_num_filt=size(FB,3); + +for j=1:total_num_filt, + F = FB(:,:,j); + a = sum(sum(abs(F))); + FB(:,:,j) = FB(:,:,j)/a; +end + diff --git a/SD-VBS/common/toolbox/toolbox_basic/filter/make_filterbank_odd.m b/SD-VBS/common/toolbox/toolbox_basic/filter/make_filterbank_odd.m new file mode 100755 index 0000000..8103598 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/filter/make_filterbank_odd.m @@ -0,0 +1,41 @@ +function FB = make_filterbank(num_ori,filter_scales,wsz) +% +% F = make_filterbank(num_ori,num_scale,wsz) +% + + +% definine filterbank +%num_ori=6; +%num_scale=3; + +num_scale = length(filter_scales); + +M1=wsz; % size in pixels +M2=M1; + +ori_incr=180/num_ori; +ori_offset=ori_incr/2; % helps with equalizing quantiz. error across filter set + +FB=zeros(M1,M2,num_ori,num_scale); + + +% elongated filter set +counter = 1; + +for m=1:num_scale + for n=1:num_ori + % r=12 here is equivalent to Malik's r=3; + f=doog1(filter_scales(m),6,ori_offset+(n-1)*ori_incr,M1); + FB(:,:,n,m)=f; + end +end + +FB=reshape(FB,M1,M2,num_scale*num_ori); +total_num_filt=size(FB,3); + +for j=1:total_num_filt, + F = FB(:,:,j); + a = sum(sum(abs(F))); + FB(:,:,j) = FB(:,:,j)/a; +end + diff --git a/SD-VBS/common/toolbox/toolbox_basic/filter/mdoog2.m b/SD-VBS/common/toolbox/toolbox_basic/filter/mdoog2.m new file mode 100755 index 0000000..25bc2f9 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/filter/mdoog2.m @@ -0,0 +1,36 @@ +function G=doog2(sig,r,th,N); +% [G,H]=doog2(sig,r,th,N); +% Make difference of offset gaussians kernel +% theta is in degrees +% (see Malik & Perona, J. Opt. Soc. Amer., 1990) +% + + +[x,y]=meshgrid(-N:N,-N:N); + +a=-1; +b=2; +c=-1; + +ya=sig; +yc=-ya; +yb=0; +sigy=sig; +sigx=r*sig; + +Ga=(1/(2*pi*sigx*sigy))*exp(-(((x-0)/sigx).^2+((y-ya)/sigy).^2)); +Gb=(1/(2*pi*sigx*sigy))*exp(-(((x-0)/sigx).^2+((y-yb)/sigy).^2)); +Gc=(1/(2*pi*sigx*sigy))*exp(-(((x-0)/sigx).^2+((y-yc)/sigy).^2)); + +Go = a*Ga + b*Gb + c*Gc; +%Ho = imag(hilbert(Go)); +G = Go; + +G = mimrotate(Go,th,'bilinear','crop'); + +G = G-mean(reshape(G,prod(size(G)),1)); + +G = G/sum(sum(abs(G))); + + + diff --git a/SD-VBS/common/toolbox/toolbox_basic/filter/mimrotate.m b/SD-VBS/common/toolbox/toolbox_basic/filter/mimrotate.m new file mode 100755 index 0000000..7dd31a2 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/filter/mimrotate.m @@ -0,0 +1,119 @@ +function bout = imrotate(arg1,arg2,arg3,arg4) +%IMROTATE Rotate image. +% B = IMROTATE(A,ANGLE,'method') rotates the image A by ANGLE +% degrees. The image returned B will, in general, be larger +% than A. Invalid values on the periphery are set to one +% for indexed images or zero for all other image types. Possible +% interpolation methods are 'nearest','bilinear' or 'bicubic'. +% 'bilinear' is the default for intensity images, otherwise +% 'nearest' is used if no method is given. +% +% B = IMROTATE(A,ANGLE,'crop') or IMROTATE(A,ANGLE,'method','crop') +% crops B to be the same size as A. +% +% Without output arguments, IMROTATE(...) displays the rotated +% image in the current axis. +% +% See also IMRESIZE, IMCROP, ROT90. + +% Clay M. Thompson 8-4-92 +% Copyright (c) 1992 by The MathWorks, Inc. +% $Revision: 1.14 $ $Date: 1993/09/01 21:27:38 $ + +if nargin<2, error('Requires at least two input parameters.'); end +if nargin<3, + if isgray(arg1), caseid = 'bil'; else caseid = 'nea'; end + docrop = 0; +elseif nargin==3, + if isstr(arg3), + method = [lower(arg3),' ']; % Protect against short method + caseid = method(1:3); + if caseid(1)=='c', % Crop string + if isgray(arg1), caseid = 'bil'; else caseid = 'nea'; end + docrop = 1; + else + docrop = 0; + end + else + error('''METHOD'' must be a string of at least three characters.'); + end +else + if isstr(arg3), + method = [lower(arg3),' ']; % Protect against short method + caseid = method(1:3); + else + error('''METHOD'' must be a string of at least three characters.'); + end + docrop = 1; +end + +% Catch and speed up 90 degree rotations +if rem(arg2,90)==0 & nargin<4, + phi = rem(arg2,360); + if phi==90, + b = rot90(arg1); + elseif phi==180, + b = rot90(arg1,2); + elseif phi==270, + b = rot90(arg1,-1); + else + b = arg1; + end + if nargout==0, imshow(b), else bout = b; end + return +end + +phi = arg2*pi/180; % Convert to radians + +% Rotation matrix +T = [cos(phi) -sin(phi); sin(phi) cos(phi)]; + +% Coordinates from center of A +[m,n] = size(arg1); +if ~docrop, % Determine limits for rotated image + siz = ceil(max(abs([(n-1)/2 -(m-1)/2;(n-1)/2 (m-1)/2]*T))/2)*2; + uu = -siz(1):siz(1); vv = -siz(2):siz(2); +else % Cropped image + uu = (1:n)-(n+1)/2; vv = (1:m)-(m+1)/2; +end +nu = length(uu); nv = length(vv); + +blk = bestblk([nv nu]); +nblks = floor([nv nu]./blk); nrem = [nv nu] - nblks.*blk; +mblocks = nblks(1); nblocks = nblks(2); +mb = blk(1); nb = blk(2); + +rows = 1:blk(1); b = zeros(nv,nu); +for i=0:mblocks, + if i==mblocks, rows = (1:nrem(1)); end + for j=0:nblocks, + if j==0, cols = 1:blk(2); elseif j==nblocks, cols=(1:nrem(2)); end + if ~isempty(rows) & ~isempty(cols) + [u,v] = meshgrid(uu(j*nb+cols),vv(i*mb+rows)); + % Rotate points + uv = [u(:) v(:)]*T'; % Rotate points + u(:) = uv(:,1)+(n+1)/2; v(:) = uv(:,2)+(m+1)/2; + if caseid(1)=='n', % Nearest neighbor interpolation + b(i*mb+rows,j*nb+cols) = interp6(arg1,u,v); + elseif all(caseid=='bil'), % Bilinear interpolation + b(i*mb+rows,j*nb+cols) = interp2(arg1,u,v,'linear'); + elseif all(caseid=='bic'), % Bicubic interpolation + b(i*mb+rows,j*nb+cols) = interp5(arg1,u,v); + else + error(['Unknown interpolation method: ',method]); + end + end + end +end + +d = find(isnan(b)); +if length(d)>0, + if isind(arg1), b(d) = ones(size(d)); else b(d) = zeros(size(d)); end +end + +if nargout==0, + imshow(b), return +end +bout = b; + + diff --git a/SD-VBS/common/toolbox/toolbox_basic/filter/mk_odd_filter.m b/SD-VBS/common/toolbox/toolbox_basic/filter/mk_odd_filter.m new file mode 100755 index 0000000..43ec7d7 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/filter/mk_odd_filter.m @@ -0,0 +1,36 @@ +function G=doog2(sig,r,th,N); +% [G,H]=doog2(sig,r,th,N); +% Make difference of offset gaussians kernel +% theta is in degrees +% (see Malik & Perona, J. Opt. Soc. Amer., 1990) +% + + +[x,y]=meshgrid(-N:N,-N:N); + +a=-1; +b=2; +c=-1; + +ya=sig; +yc=-ya; +yb=0; +sigy=sig; +sigx=r*sig; + +Ga=(1/(2*pi*sigx*sigy))*exp(-(((x-0)/sigx).^2+((y-ya)/sigy).^2)); +Gb=(1/(2*pi*sigx*sigy))*exp(-(((x-0)/sigx).^2+((y-yb)/sigy).^2)); +Gc=(1/(2*pi*sigx*sigy))*exp(-(((x-0)/sigx).^2+((y-yc)/sigy).^2)); + +Go = a*Ga + b*Gb + c*Gc; +Ho = imag(hilbert(Go)); +%G = Ho; + +G = mimrotate(Ho,th,'bilinear','crop'); + +G = G-mean(reshape(G,prod(size(G)),1)); + +G = G/sum(sum(abs(G))); + + + diff --git a/SD-VBS/common/toolbox/toolbox_basic/filter/mkdog1.m b/SD-VBS/common/toolbox/toolbox_basic/filter/mkdog1.m new file mode 100755 index 0000000..f1225cc --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/filter/mkdog1.m @@ -0,0 +1,20 @@ +function dog1 = mkdog1(sigma_base,size_w) +% +% function dog1 = mkdog1(sigma_base,size_w) +% +% + +%scale_base = 1; +scale_base = 3; + +a = scale_base; +c = -1*scale_base; + +sigma_a = 0.71*sigma_base; +sigma_c = 1.14*sigma_base; + +dog1 = a*mkg(0,0,sigma_a,sigma_a,size_w) +... + c*mkg(0,0,sigma_c,sigma_c,size_w); + +dog1 = dog1-mean(reshape(dog1,prod(size(dog1)),1)); +dog1 = dog1/sum(sum(abs(dog1))); diff --git a/SD-VBS/common/toolbox/toolbox_basic/filter/mkdog2.m b/SD-VBS/common/toolbox/toolbox_basic/filter/mkdog2.m new file mode 100755 index 0000000..a78824a --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/filter/mkdog2.m @@ -0,0 +1,22 @@ +function dog2 = mkdog2(sigma_base,size_w) +% +% function dog2 = mkdog2(sigma_base,size_w) +% +% + +%scale_base = 1.224; +scale_base = 4.15; + +a = scale_base; +b = -2*scale_base; +c = scale_base; + +sigma_a = 0.62*sigma_base; +sigma_b = sigma_base; +sigma_c = 1.6*sigma_base; + +dog2 = a*mkg(0,0,sigma_a,sigma_a,size_w) +... + b*mkg(0,0,sigma_b,sigma_b,size_w) +... + c*mkg(0,0,sigma_c,sigma_c,size_w); + +%dog2 = 255*5.1745*dog2; \ No newline at end of file diff --git a/SD-VBS/common/toolbox/toolbox_basic/filter/mkdoog2.m b/SD-VBS/common/toolbox/toolbox_basic/filter/mkdoog2.m new file mode 100755 index 0000000..5db2877 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/filter/mkdoog2.m @@ -0,0 +1,30 @@ +function doog2 = mkdoog2(sigma_w,r,theta,size_w) +% +% function doog2 = mkdoog2(sigma_w,r,theta,size_w) +% +% + +%scale_base = 2.8814; +scale_base = 2; + +a = -1*scale_base; +b = 2*scale_base; +c = -1*scale_base; + +sigma_x = r*sigma_w; +sigma_y = sigma_w; + +ya = sigma_w; +yc = -sigma_w; +yb = 0; + +doog2 = a*mkg(0,ya,sigma_x,sigma_y,size_w) +... + b*mkg(0,yb,sigma_x,sigma_y,size_w) +... + c*mkg(0,yc,sigma_x,sigma_y,size_w); + +%doog2 = 255*5.1745*doog2; + + + + + diff --git a/SD-VBS/common/toolbox/toolbox_basic/filter/mkdoogs.m b/SD-VBS/common/toolbox/toolbox_basic/filter/mkdoogs.m new file mode 100755 index 0000000..e5796bc --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/filter/mkdoogs.m @@ -0,0 +1,15 @@ +function [doogs,index] = mkdoogs(sigma_w,r,theta,theta_to,size_w) +% function doogs = mkdoogs(sigma_w,r,theta,theta_to,size_w) +% + +doogs = []; + +angle_start = theta*pi/180; +angle_end = theta_to*pi/180; +step = pi/180; + +index = 1; +for k=angle_start:step:angle_end, + doogs = [doogs,mkdoog2(sigma_w,r,k,size_w)]; + index = index +1; +end diff --git a/SD-VBS/common/toolbox/toolbox_basic/filter/mkg.m b/SD-VBS/common/toolbox/toolbox_basic/filter/mkg.m new file mode 100755 index 0000000..1fb1f7e --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/filter/mkg.m @@ -0,0 +1,9 @@ +function g= mkgaussian(xo,yo,sigma_x,sigma_y,size_w) +% +% function G = mkgaussian(xo,yo,sigma_x,sigma_y,size_w) +% + +size_wh = round(0.5*size_w); +[x,y] = meshgrid([-size_wh:1:size_wh],[-size_wh:1:size_wh]); +g = 1/(2*pi*sigma_x*sigma_y)*(exp(-( ((x-xo)/sigma_x).^2 + ((y-yo)/sigma_y).^2))); + diff --git a/SD-VBS/common/toolbox/toolbox_basic/filter/quadpair.m b/SD-VBS/common/toolbox/toolbox_basic/filter/quadpair.m new file mode 100755 index 0000000..96c2a22 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/filter/quadpair.m @@ -0,0 +1,20 @@ +function [F1,F2]=quadpair(sig,lam,th,N); +% [F1,F2]=quadpair(sig,lam,th,N); +% +% For Thomas' ECCV98 filters, use sig=sqrt(2), lam=4. + +%N=31; +[x,y]=meshgrid(-(N/2)+1/2:(N/2)-1/2,-(N/2)+1/2:(N/2)-1/2); + + +F1=(4*(y.^2)/(sig^4)-2/(sig^2)).*exp(-(y.^2)/(sig^2)-(x.^2)/(lam^2*sig^2)); +F2=imag(hilbert(F1)); + +F1=imrotate(F1,th,'bil','crop'); +F2=imrotate(F2,th,'bil','crop'); + +F1=F1-mean(F1(:)); +F2=F2-mean(F2(:)); + +F1=F1/norm(F1(:),1); +F2=F2/norm(F2(:),1); \ No newline at end of file diff --git a/SD-VBS/common/toolbox/toolbox_basic/filter/smooth.m b/SD-VBS/common/toolbox/toolbox_basic/filter/smooth.m new file mode 100755 index 0000000..5ef7579 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/filter/smooth.m @@ -0,0 +1,24 @@ +% smooth an image +% coordinates (r, c) follow matrix convention; +% the gaussian is truncated at x = +- tail, and there are samples samples +% inbetween, where samples = hsamples * 2 + 1 + +function g = smooth(image, hsamples) + +tail=4; +samples = hsamples * 2 + 1; + +x = linspace(-tail, tail, samples); +gauss = exp(-x.^2); +%s = sum(gauss)/length(x);gauss = gauss-s; +gauss = gauss/sum(abs(gauss)); + +n = gauss * ones(samples,1); +gauss = gauss/n; + + +g = conv2(conv2(image, gauss,'same'), gauss','same'); +%g = conv2(conv2(image, gauss,'valid'), gauss','valid'); + + + diff --git a/SD-VBS/common/toolbox/toolbox_basic/filter/softkmean.m b/SD-VBS/common/toolbox/toolbox_basic/filter/softkmean.m new file mode 100755 index 0000000..b9b4feb --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/filter/softkmean.m @@ -0,0 +1,56 @@ +function [cluster,var,mix,membership,lG] = softkmeans(data,k,cluster0) + +[n,D] = size(data); +var = 1.0; +var0 = ones(k,1)*var; minvar = 0.0001; +mix0 = ones(k,1)/k; minmix = 0.0001; + +k = size(var0,1); +[n,D] = size(data); + +lGG = []; +ma = -1e20; +in = 0; + +if (nargin == 2), + max_data = max(data); + min_data = min(data); + %step = (max_data-min_data)/(k+1); + %cluster0 = [1:k]'*step+min_data; + mag = ones(k,1)*(max_data-min_data); + base = ones(k,1)*min_data; + cluster0 = rand(k,D).*mag + base; +end + +%cluster0 +for t = 1:3, + %rndindx = round(rand(1,k)*(n-3))+2; + %cluster0 = (data(rndindx,:)+data(rndindx+1,:)+data(rndindx-1,:))/2; + [cluster,var,mix,membership,lG] = softmeans(cluster0,var0,minvar,mix0,minmix,data); + eval(sprintf('mix_var_cluster_%d = [mix,var,cluster];',t)); + eval(sprintf('lG_%d = lG;',t)); + if ma 1, Hj = sum(Hj')'; end + H(:,j) = exp(Hj /(-2*var_p(j)))/(sqrt(var_p(j))^D); + end + H = H.*(ones(n,1)*mix_p'); + new_lg = sum(log(sum(H')/(sqrt(2*pi)^D))); + lG = [lG, new_lg]; + if new_lg == old_lg, break; end; old_lg = new_lg; + H = H./(sum(H')'*ones(1,k)); % normalize + + % M-Step: + + if minmix > 0, + mix_p = sum(H); mix_p = mix_p/sum(mix_p); mix_p = mix_p'; + for j = 1:k, if mix_p(j) 0, + for j = 1:k, + varj = (data-(ones(n,1)*cluster_p(j,:))).^2; + if D > 1, varj = sum(varj')'; end + var_p(j) = sum(H(:,j).*varj)/(D*sum(H(:,j))); + if var_p(j)'); +end + +fprintf('\n'); + +s = 1./sqrt(d); + +for j=1:nv, + v(:,j) = v(:,j)*s(j); +end + + diff --git a/SD-VBS/common/toolbox/toolbox_basic/filter_hist/backproj_outer_chank2.m b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/backproj_outer_chank2.m new file mode 100755 index 0000000..084c150 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/backproj_outer_chank2.m @@ -0,0 +1,36 @@ +function v = backproj_outer_chank(fvs,u,d,chank_size) +% +% given the eigenvecs of the hist.bin. features +% computes the back projection on the eigenvects +% + +[nv,np] = size(fvs); +[nbins,nv] = size(u); + +n_chanks = ceil(np/chank_size); + +v = ones(np,nv); + +for j=1:n_chanks, + fprintf('<'); + + cm = sprintf('load st_%d',j); + eval(cm); + fprintf(sprintf('%d',n_chanks-j)); + + ms = mean(fh'); + fh = fh - ms'*ones(1,size(fh,2)); + + v((j-1)*chank_size+1:min(np,j*chank_size),:) = fh'*u; + fprintf('>'); +end + +fprintf('\n'); + +s = 1./sqrt(d); + +for j=1:nv, + v(:,j) = v(:,j)*s(j); +end + + diff --git a/SD-VBS/common/toolbox/toolbox_basic/filter_hist/binize.m b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/binize.m new file mode 100755 index 0000000..d166cd5 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/binize.m @@ -0,0 +1,15 @@ +function [binv,bins] = binize(data,sig,bin_min,bin_max,num_bin) +% +% given an input data, and sigma which describes the uncertainty +% of the data, along with information on the bins, +% return the soft-hist on data +% + +ndata = length(data); + +bins = linspace(bin_min,bin_max,num_bin+1); +binv = zeros(num_bin,ndata); + +for j=1:num_bin, + binv(j,:) = erf((bins(j+1)-data)/sig) - erf((bins(j)-data)/sig); +end diff --git a/SD-VBS/common/toolbox/toolbox_basic/filter_hist/binize_old.m b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/binize_old.m new file mode 100755 index 0000000..d56d263 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/binize_old.m @@ -0,0 +1,34 @@ +function [binv,bins] = binize(data,sig,bin_min,bin_max,num_bin) +% +% given an input data, and sigma which describes the uncertainty +% of the data, along with information on the bins, +% return the soft-hist on data +% + +ndata = length(data); + +if 0, +bins = linspace(bin_min,bin_max,num_bin); +binv = zeros(num_bin,ndata); + +Largev = 1000; + +bins = [-Largev,bins]; + +for j=1:num_bin, + binv(j,:) = erf((bins(j+1)-data)/sig) - erf((bins(j)-data)/sig); +end + +binv(num_bin,:) = binv(num_bin,:) + erf((Largev-data)/sig) - erf((bins(end)-data)/sig); +bins = bins(2:end); +else + +bins = linspace(bin_min,bin_max,num_bin+1); +binv = zeros(num_bin,ndata); + + +for j=1:num_bin, + binv(j,:) = erf((bins(j+1)-data)/sig) - erf((bins(j)-data)/sig); +end + +end \ No newline at end of file diff --git a/SD-VBS/common/toolbox/toolbox_basic/filter_hist/binomialfield.m b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/binomialfield.m new file mode 100755 index 0000000..d83d96d --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/binomialfield.m @@ -0,0 +1,75 @@ +function [x,y,success] = BinomialField(n,sx,sy,ir,numtri); +%BF_HardCore Generates a hard core binomial field +% [x,y,success] = BinomialField(n,sx,sy,ir); +% n : # points (default 100) +% sx : size in x (default 100) +% sy : size in y (default 100) +% ir : inhibition radius (default 0) +% numtri : number of trials (default 200) +% x : x coordinates +% y : y coordinates +% success: whether success or not, useful when producing hard core model + +%% +%% (C) Thomas K. Leung +%% University of California at Berkeley +%% April 26, 1995. +%% leungt@cajal.cs.berkeley.edu +%% + +%% +%% Generate n points first and then reject those closer to the +%% previous points than ir +%% + +if nargin < 1 + n = 100; + sx = 100; + sy = 100; + ir = 0; + numtri = 200; +elseif (nargin == 1 | nargin == 2) + sx = 100; + sy = 100; + ir = 0; + numtri = 200; +elseif (nargin == 3) + ir = 0; + numtri = 200; +elseif (nargin == 4) + numtri = 200; +end + +x = zeros(1,n); +y = zeros(1,n); + +rand('seed',sum(100*clock)); +x(1) = rand(1) * sx; +y(1) = rand(1) * sy; + +success = 1; + +I = 2; +trial = 0; +while (I <= n & trial < numtri) + found = 0; + trial = 0; + while (~found & trial < numtri); + tx = rand(1) * sx; + ty = rand(1) * sy; + D = (x(1:(I-1)) - tx).^2 + (y(1:(I-1)) - ty).^2; + if sum(D > (ir^2)) == (I-1) + found = 1; + x(I) = tx; + y(I) = ty; + end + trial = trial + 1; + end + I = I + 1; +end + +if trial >= numtri + fprintf(1,'Failed to generate a point in %d trials\n',numtri); + success = 0; +end + diff --git a/SD-VBS/common/toolbox/toolbox_basic/filter_hist/colize.m b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/colize.m new file mode 100755 index 0000000..b03616f --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/colize.m @@ -0,0 +1,9 @@ +function t1a = colize(t1,I1); + +t1a = t1; + +t1a = reshape(t1a,size(t1,1)*size(t1,2),1,size(t1,3)); +t1a = squeeze(t1a); +t1a = t1a'; + +%I1a = 2*I1(:)';I1a = I1a-mean(I1a(:));t1a = [I1a;t1a]; diff --git a/SD-VBS/common/toolbox/toolbox_basic/filter_hist/colize_hist.m b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/colize_hist.m new file mode 100755 index 0000000..9c7b68e --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/colize_hist.m @@ -0,0 +1,29 @@ +function fh = colize_hist(fv,hb) +% (hb = sigs,bin_mins,bin_maxs,nbins) +% +% fv = [nfeature x npoints]; +% fh = [nfeatures*nbins x npoints]; +% +% take a feature matrix, and turn it into histogram bin feature matrix +% +% + +[nf,np] = size(fv); + +nbins = [0,hb.nbins]; +disp(sprintf('need matrix of %d x %d ',sum(nbins),np)); + +fh = zeros(sum(nbins),np); + +for k=1:nf, + bin_min = hb.bmins(k); + bin_max = hb.bmaxs(k); + nbin = nbins(k+1); + sig = hb.sigs(k); + fprintf('.'); + b = binize(fv(k,:),sig,bin_min,bin_max,nbin); + fh(sum(nbins(1:k))+1:sum(nbins(1:k+1)),:) = b; + +end + +fprintf('\n'); diff --git a/SD-VBS/common/toolbox/toolbox_basic/filter_hist/colize_histnb_s.m b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/colize_histnb_s.m new file mode 100755 index 0000000..61c81ca --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/colize_histnb_s.m @@ -0,0 +1,47 @@ +function fhs = colize_histnb_s(fh,Is,nw,hw) +% +% fhs = colize_histneigh(fh,fvs,nw) +% +% + +[tnbins,np] = size(fh); + +[nr,nc] = size(Is); + +st_sz = 2*hw + 1; + +nr_chank = floor(nr/st_sz); +nc_chank = floor(nc/st_sz); + +fhs = zeros(size(fh,1),nr_chank*nc_chank); + +idx = 0; +for k=1+hw:st_sz:nc-hw, + + fprintf('.'); + sk = max(1,k-nw); + ek = min(nc,k+nw); + + + % for each column, + for j=1+hw:st_sz:nr-hw, + sj = max(1,j-nw); + ej = min(nr,j+nw); + + id = j+(k-1)*nr; + idx = idx+1; + for li=sj:ej, + for lj=sk:ek, + idn = li+(lj-1)*nr; + + fhs(:,idx) = fhs(:,idx) + fh(:,idn); + + end + end + end +end + +fprintf('\n'); + + + \ No newline at end of file diff --git a/SD-VBS/common/toolbox/toolbox_basic/filter_hist/colize_histnb_sf.m b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/colize_histnb_sf.m new file mode 100755 index 0000000..d0d60f9 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/colize_histnb_sf.m @@ -0,0 +1,52 @@ +function fhs = colize_histnb_s(fvs,Is,hb,nw,hw) +% +% fhs = colize_histneigh(fvs,Is,hb,nw,hw) +% +% + +[nf,np] = size(fvs); + +[nr,nc] = size(Is); + +st_sz = 2*hw + 1; + +nr_chank = floor(nr/st_sz); +nc_chank = floor(nc/st_sz); + +tnbins = prod(hb.nbins(1:nf)); +disp(sprintf('allocat memory for %d x %d',tnbins,nr_chank*nc_chank)); + +fhs = zeros(tnbins,nr_chank*nc_chank); + +idx = 0; +for k=1+hw:st_sz:nc-hw, + + fprintf(','); + sk = max(1,k-nw); + ek = min(nc,k+nw); + + + % for each column, + for j=1+hw:st_sz:nr-hw, + sj = max(1,j-nw); + ej = min(nr,j+nw); + + id = j+(k-1)*nr; + idx = idx+1; + + %% find idx for the neighboring points + lis = [sj:ej]'*ones(1,ek-sk+1); + ljs = ones(ej-sj+1,1)*[sk:ek]; + idns = lis+(ljs-1)*nr; + + fh = colize_joint_hist(fvs(:,idns(:)),hb); + + fhs(:,idx) = sum(fh')'; + + end +end + +fprintf('\n'); + + + \ No newline at end of file diff --git a/SD-VBS/common/toolbox/toolbox_basic/filter_hist/colize_histneighb.m b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/colize_histneighb.m new file mode 100755 index 0000000..6189cab --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/colize_histneighb.m @@ -0,0 +1,37 @@ +function fhs = colize_histneigh(fh,Is,nw) +% +% fhs = colize_histneigh(fh,fvs,nw) +% +% + +[tnbins,np] = size(fh); + +[nr,nc] = size(Is); + +fhs = zeros(size(fh)); + +for j=1:nr, + fprintf('.'); + sj = max(1,j-nw); + ej = min(nr,j+nw); + + % for each column, + for k=1:nc, + sk = max(1,k-nw); + ek = min(nc,k+nw); + + id = j+(k-1)*nr; + + for li=sj:ej, + for lj=sk:ek, + idn = li+(lj-1)*nr; + + fhs(:,id) = fhs(:,id) + fh(:,idn); + end + end + end +end +fprintf('\n'); + + + \ No newline at end of file diff --git a/SD-VBS/common/toolbox/toolbox_basic/filter_hist/colize_joint_hist.m b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/colize_joint_hist.m new file mode 100755 index 0000000..e7844d8 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/colize_joint_hist.m @@ -0,0 +1,41 @@ +function fh = colize_joint_hist(fv,hb) +% (hb = sigs,bin_mins,bin_maxs,nbins) +% +% take which histogram value and turn it into histogram bin +% + + + [nf,np] = size(fv); + + nbins = [0,hb.nbins]; + %disp(sprintf('need matrix of %d x %d ',prod(hb.nbins),np)); + + fh = zeros(hb.nbins(1),hb.nbins(2),np); + + k=1; + bin_min = hb.bmins(k); + bin_max = hb.bmaxs(k); + nbin = nbins(k+1); + sig = hb.sigs(k); + %fprintf('.'); + + b1 = binize(fv(k,:),sig,bin_min,bin_max,nbin); + k=2; + bin_min = hb.bmins(k); + bin_max = hb.bmaxs(k); + nbin = nbins(k+1); + sig = hb.sigs(k); + %fprintf('.'); + + b2 = binize(fv(k,:),sig,bin_min,bin_max,nbin); + + + for k=1:hb.nbins(1), + for j=1:hb.nbins(2), + fh(k,j,:) = b1(k,:).*b2(j,:); + end + end + +%fprintf('\n'); + +fh = reshape(fh,hb.nbins(1)*hb.nbins(2),np); diff --git a/SD-VBS/common/toolbox/toolbox_basic/filter_hist/colize_test.m b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/colize_test.m new file mode 100755 index 0000000..a9135cc --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/colize_test.m @@ -0,0 +1,19 @@ +function t1a = colize(t1,I1); + +if 1, +t1a = t1; +%t1a = 1.2*half_sigmoid(t1,0.3,0.1);; +t1a = reshape(t1a,size(t1,1)*size(t1,2),1,size(t1,3)); +t1a = squeeze(t1a); +t1a = t1a'; + +%I1a = I1(:)';I1a = I1a-mean(I1a(:));t1a = [I1a;t1a]; + +else + mask = t1>=0; + t1a = abs(t1); + t1a = 0.5-t1a; + t1a = reshape(t1a,size(t1,1)*size(t1,2),1,size(t1,3)); + t1a = squeeze(t1a); + t1a = t1a'; +end diff --git a/SD-VBS/common/toolbox/toolbox_basic/filter_hist/compact.m b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/compact.m new file mode 100755 index 0000000..9863e0f --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/compact.m @@ -0,0 +1,36 @@ +function I = compact(img,ws) + + +%ws = 2*hws+1; + +[sy,sx] = size(img); + +rem_x = rem(sx,ws); +rem_y = rem(sy,ws); + +fix_x = ceil(sx/ws); +fix_y = ceil(sy/ws); + +fprintf('nr = %d, nc = %d\n',fix_y,fix_x); + +%startx= 1 + floor(rem_x*0.5)+hws; +%starty= 1 + floor(rem_y*0.5)+hws; + +I = zeros(fix_y,fix_x); + +yid = 0; +for j=1:ws:sy, + xid = 0; + yid = yid +1; + fprintf('.'); + for k=1:ws:sx, + xid = xid+1; + %I(yid,xid) = median(median(img(j-hws:j+hws,k-hws:k+hws))); + %I(yid,xid) = sum(sum(img(j-hws:j+hws,k-hws:k+hws))); + v = img(j:min(sy,j+ws-1),k:min(sx,k+ws-1)); + %I(yid,xid) = median(reshape(v,prod(size(v)),1)); + I(yid,xid) = median(median(v)); + end +end +fprintf('\n'); + \ No newline at end of file diff --git a/SD-VBS/common/toolbox/toolbox_basic/filter_hist/compute_J.m b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/compute_J.m new file mode 100755 index 0000000..99b8b69 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/compute_J.m @@ -0,0 +1,31 @@ +function J = compute_J(A,I,size_x,size_y,D) +%% function J = compute_J(A,I,size_x,size_y,D) +% + +[center_x,center_y] = find_center(size_x,size_y); + +tmp = ones(size_y,1)*[1:size_x]; +index(:,1) = reshape(tmp,size_x*size_y,1)-center_x*ones(size_x*size_y,1); +index(:,2) = reshape(tmp',size_x*size_y,1)-center_y*ones(size_x*size_y,1); + +position_new = A*index'+ [D(1),0;0,D(2)]*ones(2,size_x*size_y); +position_new = round(position_new +... + [center_x,0;0,center_y]*ones(2,size_x*size_y)); +% we have to deal with out of boundary ones +% +bad_ones(1,:) = position_new(1,:)<1 | position_new(1,:)>size_x; +bad_ones(2,:) = position_new(2,:)<1 | position_new(2,:)>size_y; +bad = max([bad_ones(1,:);bad_ones(2,:)]); +good = ~bad; +% if new index is out of boundary, then set it to (0,0) +position_new(1,:) = position_new(1,:).*good; +position_new(2,:) = position_new(2,:).*good; + +new_index = size_y*(position_new(1,:)-ones(1,size_x*size_y))+... + position_new(2,:); +new_index = max([new_index;ones(1,size_x*size_y)]); +J = I(new_index); +% set the "out of boundary" to zero. +J = J.*good; +J = reshape(J',size_y,size_x); + diff --git a/SD-VBS/common/toolbox/toolbox_basic/filter_hist/compute_Lf.m b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/compute_Lf.m new file mode 100755 index 0000000..7cda523 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/compute_Lf.m @@ -0,0 +1,35 @@ +function dists = compute_Lf(F,cts,wz,nr,nc) + +gap = 2*wz(1)+1; +hw = wz(1); + +nr = nr+1; +nc = nc+1; + +dists = zeros(size(cts,1),nr*nc); +for ctj = 1:size(cts,1), + t1 = cutout(F,cts(ctj,:),wz); + + rid = 1; + fprintf('>'); + + for ri = hw+1:gap:size(F,1)-hw, + %fprintf('[%d]',ri); + cid = 1; + for ci = hw+1:gap:size(F,2)-hw, + %fprintf('(%d)',ci); + t2 = cutout(F,[ci,ri],wz); + + dist = abs(mean(t1(:))-mean(t2(:))); + + dists(ctj,rid+cid*nr) = max(dist,dists(ctj,rid+cid*nr)); + + cid = cid+1; + end + rid = rid+1; + end + + %fprintf('\n'); + +end + diff --git a/SD-VBS/common/toolbox/toolbox_basic/filter_hist/compute_corr.m b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/compute_corr.m new file mode 100755 index 0000000..92f9da4 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/compute_corr.m @@ -0,0 +1,10 @@ +function a = compute_corr(f,g) +% +% compute the circular correlation of f and g +% at points around zero +% +% + +ff = interp(f,4); +gg = interp(g,4); + diff --git a/SD-VBS/common/toolbox/toolbox_basic/filter_hist/compute_diff.m b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/compute_diff.m new file mode 100755 index 0000000..72bfe54 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/compute_diff.m @@ -0,0 +1,36 @@ +function B = compute_diff(Ja,Jfa,hw,hnb); +% +% B = compute_diff(Ja,Jfa,hw,hnb) +% +% + +figure(1);%imagesc(Ja);axis('image'); +cs = round(ginput(1)); + +B = zeros(2*hnb+1,2*hnb+1); + +scales = [1:5];filter_ids = [1:7]; +Jc = get_win(Ja,cs,[hw,hw]); +Jfc= get_win5(Jfa,cs,[hw,hw]); +H2c = hist2d(Jc,Jfc,scales,filter_ids); + +figure(2);imagesc(Ja);axis('image');colormap(gray); +hold on; plot(cs(1),cs(2),'g*'); + + +for ii=-hnb:hnb, + for jj=-hnb:hnb, + J1 = get_win(Ja,cs+4*[jj,ii],[hw,hw]); + Jf1= get_win5(Jfa,cs+4*[jj,ii],[hw,hw]); + figure(2);plot(cs(1)+4*jj,cs(2)+4*ii,'ro');drawnow; + %figure(3);imagesc(J1);drawnow; + + H2 = hist2d(J1,Jf1,scales,filter_ids); + d = hist_diff(H2/prod(size(Jc)),H2c/prod(size(Jc))); + disp(sprintf('d=%f',d)); + B(ii+hnb+1,jj+hnb+1) = d; + + end +end + +figure(2);hold off; diff --git a/SD-VBS/common/toolbox/toolbox_basic/filter_hist/compute_diff_patch.m b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/compute_diff_patch.m new file mode 100755 index 0000000..260b93a --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/compute_diff_patch.m @@ -0,0 +1,34 @@ +function a = compute_diff_patch(gx1,gy1,gx2,gy2,I1,I2) +% +% a = compute_diff_patch(gx1,gy1,gx2,gy2,I1,I2) +% +% + +%ws = size(gx1); +%mask = smooth(ones(ws),2*max(ws)); +%mask = mask/sum(sum(mask)); + +%mag1= sum(sum(sqrt((mask.*gx1).^2 + (mask.*gy1).^2))); +%mag2= sum(sum(sqrt((mask.*gx2).^2 + (mask.*gy2).^2))); + +mag1= sum(sum(sqrt((gx1).^2 + (gy1).^2))); +mag2= sum(sum(sqrt((gx2).^2 + (gy2).^2))); + +P_tx1 = sigmoid(mag1,400,80); +P_tx2 = sigmoid(mag2,400,80); + +diff_I = mean(reshape(I1,prod(size(I1)),1))-... + mean(reshape(I2,prod(size(I2)),1)); +diff_I = abs(diff_I); + +s_g1 = [sum(sum(abs(gx1))),sum(sum(abs(gy1)))]; +s_g2 = [sum(sum(abs(gx2))),sum(sum(abs(gy2)))]; + +s_g1 = s_g1/(norm(s_g1)); +s_g2 = s_g2/(norm(s_g2)); + +a = (1-P_tx1)*(1-P_tx2)*exp(-diff_I/0.1) +... + P_tx1*P_tx2*(dot(s_g1,s_g2)); + + + diff --git a/SD-VBS/common/toolbox/toolbox_basic/filter_hist/compute_diff_patch2.m b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/compute_diff_patch2.m new file mode 100755 index 0000000..9d2b528 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/compute_diff_patch2.m @@ -0,0 +1,45 @@ +function [a,phi1,phi2] = compute_diff_patch(gx1,gy1,gx2,gy2,I1,I2) +% +% a = compute_diff_patch(gx1,gy1,gx2,gy2,I1,I2) +% +% + +%ws = size(gx1); +%mask = smooth(ones(ws),2*max(ws)); +%mask = mask/sum(sum(mask)); + +%mag1= sum(sum(sqrt((mask.*gx1).^2 + (mask.*gy1).^2))); +%mag2= sum(sum(sqrt((mask.*gx2).^2 + (mask.*gy2).^2))); + +mag1= sum(sum(sqrt((gx1).^2 + (gy1).^2)))/prod(size(gx1)); +mag2= sum(sum(sqrt((gx2).^2 + (gy2).^2)))/prod(size(gx1)); + +P_tx1 = sigmoid(mag1,2,0.5); +P_tx2 = sigmoid(mag2,2,0.5); + +diff_I = mean(reshape(I1,prod(size(I1)),1))-... + mean(reshape(I2,prod(size(I2)),1)); +diff_I = abs(diff_I); + +[l1,l2,phi1] = mwis(gx1,gy1); +[k1,k2,phi2] = mwis(gx2,gy2); + +ratio1 = min([l1,l2])/max([l1,l2]); +ratio2 = min([k1,k2])/max([k1,k2]); + +r1 = 1-sigmoid(ratio1,0.35,0.05); +r2 = 1-sigmoid(ratio2,0.35,0.05); + +s1 = [cos(phi1),sin(phi1)]; +s2 = [cos(phi2),sin(phi2)]; + +angle = acos(abs(dot(s1,s2)))*180/pi; + +a1 = (1-P_tx1*P_tx2)*exp(-diff_I/0.1); +a2 = P_tx1*P_tx2*(r1*r2*(90-angle)/90); +a3 = P_tx1*P_tx2*((1-r1*r2)*(1-sigmoid(abs(r1-r2),0.3,0.04))); + +a = a1+a2+a3; + + + diff --git a/SD-VBS/common/toolbox/toolbox_basic/filter_hist/compute_filter.m b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/compute_filter.m new file mode 100755 index 0000000..04e78e1 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/compute_filter.m @@ -0,0 +1,84 @@ +function [filter_output,filters] = compute_filter(I,sig,r,sz); +% +% +% + +ori_incr=180/num_ori; +ori_offset=ori_incr/2; % helps with equalizing quantiz. error across filter set + +as = ori_offset:ori_incr:180+ori_offset-ori_incr; + +filter_output = []; +filters = []; + +wsz = 2*round(sz) + 1; +M1 = wsz(1);M2 = wsz(2); + +%%%%% prepare FFT of image %%%%%%%%%%%%% + +[N1,N2]=size(I); +tmp=zeros(size(I)+[M1-1 M2-1]); +tmp(1:N1,1:N2)=I; +IF=fft2(tmp); + + +%%%%%%%%%% filtering stage %%%%%%%%%%% +if size(sig,2)== 1, + + for j = 1:length(as), + fprintf('.'); + angle = as(j); + + g = mdoog2(sig,r,angle,round(sz)); + + g = g - mean(reshape(g,prod(size(g)),1)); + + g = g/sum(sum(abs(g))); + + filters(:,:,j) = g; + + gF = fft2(g,N1+M1-1,N2+M2-1); + IgF = If.*gF; + Ig = real(ifft2(IgF)); + Ig = Ig(ceil((M1+1)/2):ceil((M1+1)/2)+N1-1,ceil((M2+1)/2):ceil((M2+1)/2)+N2-1); + + %c = conv2(I,g,'valid'); + + filter_output(:,:,j) = Ig; + end +else + + % there are multiple scales + sigs = sig; + szs = sz; + for k = 1:size(sigs,2), + sig = sigs(k); + sz = szs(k); + fprintf('%d',k); + for j = 1:length(as), + fprintf('.'); + angle = as(j); + + g = mdoog2(sig,r,angle,round(sz)); + g = g - mean(reshape(g,prod(size(g)),1)); + g = g/sum(sum(abs(g))); + + gF = fft2(g,N1+M1-1,N2+M2-1); + IgF = If.*gF; + Ig = real(ifft2(IgF)); + Ig = Ig(ceil((M1+1)/2):ceil((M1+1)/2)+N1-1,ceil((M2+1)/2):ceil((M2+1)/2)+N2-1); + + %c = conv2(I,g,'valid'); + %c = conv2(I,g,'same'); + + filter_output(:,:,j,k) = Ig; + filters(:,:,j,k) = g; + end + + + end + +end + +fprintf('\n'); + diff --git a/SD-VBS/common/toolbox/toolbox_basic/filter_hist/compute_filter_fft.m b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/compute_filter_fft.m new file mode 100755 index 0000000..359c6ba --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/compute_filter_fft.m @@ -0,0 +1,84 @@ +function [filter_output,filters] = compute_filter_fft(I,sig,r,sz,num_ori); +% +% +% + +ori_incr=180/num_ori; +ori_offset=ori_incr/2; % helps with equalizing quantiz. error across filter set + +as = ori_offset:ori_incr:180+ori_offset-ori_incr; + +filter_output = []; +filters = []; + +wsz = 2*round(sz(end)) + 1; +M1 = wsz;M2 = wsz; + +%%%%% prepare FFT of image %%%%%%%%%%%%% + +[N1,N2]=size(I); +tmp=zeros(size(I)+[M1-1 M2-1]); +tmp(1:N1,1:N2)=I; +IF=fft2(tmp); + + +%%%%%%%%%% filtering stage %%%%%%%%%%% +if size(sig,2)== 1, + + for j = 1:length(as), + fprintf('.'); + angle = as(j); + + g = mdoog2(sig,r,angle,round(sz)); + + g = g - mean(reshape(g,prod(size(g)),1)); + + g = g/sum(sum(abs(g))); + + filters(:,:,j) = g; + + gF = fft2(g,N1+M1-1,N2+M2-1); + IgF = IF.*gF; + Ig = real(ifft2(IgF)); + Ig = Ig(ceil((M1+1)/2):ceil((M1+1)/2)+N1-1,ceil((M2+1)/2):ceil((M2+1)/2)+N2-1); + + %c = conv2(I,g,'valid'); + + filter_output(:,:,j) = Ig; + end +else + + % there are multiple scales + sigs = sig; + szs = sz; + for k = 1:size(sigs,2), + sig = sigs(k); + sz = szs(end); + fprintf('%d',k); + for j = 1:length(as), + fprintf('.'); + angle = as(j); + + g = mdoog2(sig,r,angle,round(sz)); + g = g - mean(reshape(g,prod(size(g)),1)); + g = g/sum(sum(abs(g))); + + gF = fft2(g,N1+M1-1,N2+M2-1); + IgF = IF.*gF; + Ig = real(ifft2(IgF)); + Ig = Ig(ceil((M1+1)/2):ceil((M1+1)/2)+N1-1,ceil((M2+1)/2):ceil((M2+1)/2)+N2-1); + + %c = conv2(I,g,'valid'); + %c = conv2(I,g,'same'); + + filter_output(:,:,j,k) = Ig; + filters(:,:,j,k) = g; + end + + + end + +end + +fprintf('\n'); + diff --git a/SD-VBS/common/toolbox/toolbox_basic/filter_hist/conv_trim.m b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/conv_trim.m new file mode 100755 index 0000000..30d16a9 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/conv_trim.m @@ -0,0 +1,6 @@ +% trims an array to remove meaningless pixels after a convolution with +% an r * c window + +function[B] = conv_trim(A, r, c) + +B = A(r+1:size(A,1)-r, c+1:size(A,2)-c); diff --git a/SD-VBS/common/toolbox/toolbox_basic/filter_hist/corr_hist.m b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/corr_hist.m new file mode 100755 index 0000000..c538dc1 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/corr_hist.m @@ -0,0 +1,9 @@ +function alpha = corr_hist(hists) + +[y,x,v] = find(hists); +mx = sum(x.*v)/sum(v); +my = sum(y.*v)/sum(v); + +top = sum( (x-mx).*(y-my).*v); +bottom = sqrt(sum( ((x-mx).^2).*v))*sqrt(sum( ((y-my).^2).*v)); +alpha = top/bottom; diff --git a/SD-VBS/common/toolbox/toolbox_basic/filter_hist/crop_im_fil.m b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/crop_im_fil.m new file mode 100755 index 0000000..5472171 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/crop_im_fil.m @@ -0,0 +1,11 @@ +function [J,f,rect] = crop_im_fil(Ja,Jfa,fig_id) +% +% + +figure(fig_id); +imagesc(Ja);axis('image'); + +[J,rect] = imcrop;rect = round(rect); +J = Ja(rect(2):rect(2)+rect(4),rect(1):rect(1)+rect(3)); +f = Jfa(rect(2):rect(2)+rect(4),rect(1):rect(1)+rect(3),:,:); + diff --git a/SD-VBS/common/toolbox/toolbox_basic/filter_hist/cutoff.m b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/cutoff.m new file mode 100755 index 0000000..58c6b94 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/cutoff.m @@ -0,0 +1,13 @@ +function I = cutoff(I,wc) +% +% + +nr = size(I,1); +nc = size(I,2); + +if ndims(I) == 3, +I = I(wc+1:nr-wc,wc+1:nc-wc,:,:); +else +I = I(wc+1:nr-wc,wc+1:nc-wc,:,:); +end + diff --git a/SD-VBS/common/toolbox/toolbox_basic/filter_hist/cutout.m b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/cutout.m new file mode 100755 index 0000000..b80f27b --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/cutout.m @@ -0,0 +1,3 @@ +function a = cutout(I,ct,wz); + +a = I(ct(2)-wz(2):ct(2)+wz(2),ct(1)-wz(1):ct(1)+wz(1),:); diff --git a/SD-VBS/common/toolbox/toolbox_basic/filter_hist/disp_Imask.m b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/disp_Imask.m new file mode 100755 index 0000000..dbd7fdb --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/disp_Imask.m @@ -0,0 +1,20 @@ +function Imasks = disp_Imask(Is,nr,nc,hw,masks) +% +% Imasks = disp_Imask(Is,nr,nc,hw,masks) +% + +%hw = 2; %nr = 43;nc=68; +gap = 2*hw+1; + +x = [1:nc*gap]; +y = [1:nr*gap]; + +xs = (x-hw-1)/gap + 1;ys = (y-hw-1)/gap + 1; + +for gid=1:size(masks,3), + tmp = interp2(reshape(masks(:,:,gid),nr,nc),xs,ys'); + + Imasks(:,:,gid) = (tmp>0.52).* ((Is).^0.8); + subplot(3,3,gid); + im(Imasks(:,:,gid)); +end diff --git a/SD-VBS/common/toolbox/toolbox_basic/filter_hist/disp_diff.m b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/disp_diff.m new file mode 100755 index 0000000..090c273 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/disp_diff.m @@ -0,0 +1,37 @@ +function disp_diff(H1,H2) +% +% disp_diff(H1,H2) +% + +ns = size(H1,3); +nf = size(H1,4); + +H1 = H1/49; +H2 = H2/49; + + +sI= [1,0,1];sI = exp(-sI); +sI = sI/sum(sI); + +for j = 1:ns, + for k = 1:nf, + h1 = H1(:,:,j,k); + h2 = H2(:,:,j,k); + + subplot(ns,nf,(j-1)*nf+k); + h1s = conv2(conv2(h1,sI','same'),sI,'same'); + h2s = conv2(conv2(h2,sI','same'),sI,'same'); + + [is,js] = find( (h1>0) | (h2>0)); + ids = (js-1)*size(h1,1) + is; + + hdiff = abs(h1s-h2s).*((h1>0) | (h2>0)); + + xdiff = ((h1(ids)-h2(ids)).*(h1(ids)-h2(ids)))./(h1(ids)+h2(ids)); + + xdiffs = ((h1s(ids)-h2s(ids)).*(h1s(ids)-h2s(ids)))./(h1s(ids)+h2s(ids)); + imagesc(hdiff);colorbar;axis('off'); +% title(sprintf('%3.3f, %3.3f',sum(sum(hdiff))/49,sum(sum(abs(h1-h2)))/49));drawnow; + title(sprintf('%3.3f, %3.3f',sum(xdiff),sum(xdiffs)));drawnow + end +end diff --git a/SD-VBS/common/toolbox/toolbox_basic/filter_hist/disp_evresult.m b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/disp_evresult.m new file mode 100755 index 0000000..e07556a --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/disp_evresult.m @@ -0,0 +1,435 @@ +%fn = '134035'; +%fn = '130040'; +%fn = '334074'; +fn = '130065'; + +%basedir = 'plaatje_data/olddata/'; +% basedir = 'data/'; nr = 49;nc =30; + +basedir = 'plaatje_data/'; + +fname = sprintf('%s%s_eigvec.pfm',basedir,fn); +eigv = readpfm(fname); +fname = sprintf('%s%s_eigval.pfm',basedir,fn); +eigval = readpfm(fname); + +fname = sprintf('%s%s_ncutvec.pfm',basedir,fn); +ncutv = readpfm(fname); +fname = sprintf('%s%s_ncutval.pfm',basedir,fn); +ncutval = readpfm(fname); + +%fname = sprintf('images/130039.pgm'); +fname = sprintf('images/%s.pgm',fn); +I = readpgm(fname); +cutsz = 20; I = cutoff(I,cutsz); +figure(3);im(I);colormap(gray); + +new = 0; + +if ~new, + + %nr = 49;nc = 30; + nr = 30;nc = 49; + +%nr = 68;nc = 43; +%nc = 68;nr = 43; + +else + + fn1 = fn; + fn = 'test'; + fname = sprintf('plaatje_data/%s_gcs.pfm',fn); + gcs = readpfm(fname); + + fname = sprintf('plaatje_data/%s_gce.pfm',fn); + gce = readpfm(fname); + + fname = sprintf('plaatje_data/%s_grs.pfm',fn); + grs = readpfm(fname); + + fname = sprintf('plaatje_data/%s_gre.pfm',fn); + gre = readpfm(fname); + + nr = max(gre(:))+1; + nc = max(gce(:))+1; + + fn = fn1; + +end + +figure(6); +for j=1:8, + subplot(3,3,j); + im(reshape(ncutv(:,j+1),nr,nc));colorbar + title(num2str(ncutval(j+1,1))); +end +%cm = sprintf('print -dps ncut_%s',fn);disp(cm);eval(cm); +subplot(3,3,9);im(I);axis('off'); + +figure(7);clf +for j=1:12, + subplot(3,4,j); + im(reshape(eigv(:,j),nr,nc));colorbar;%axis('off'); + title(sprintf('%3.4e',eigval(j,1))); +end +%cm = sprintf('print -dps eig_%s',fn);disp(cm);eval(cm); + +%%%%%%%%%%% + +ev = eigval(:,1); +figure(5);hold off;clf;subplot(1,2,1); +%semilogy((ev(1:end-1) - ev(2:end))./ev(1:end-1),'x-');grid on; +plot((ev(1:end-1) - ev(2:end))./ev(1:end-1),'x-');grid on; +%semilogy(0.01*ones(size(ev(2:end-1))),'r-');semilogy(0.005*ones(size(ev(2:end-1))),'r-');semilogy(0.0025*ones(size(ev(2:end-1))),'r-');grid on;hold off; +subplot(1,2,2); +%semilogy(ev(1:end-1)-ev(2:end),'p-');grid on; +semilogy((ev(1:end-1) - ev(2:end))/ev(1),'x-');grid on; + + +if 0, + +fname = sprintf('plaatje_data/ncutval_%s.pfm',fn); +nval = readpfm(fname); +fname = sprintf('plaatje_data/ncutvec_%s.pfm',fn); +nv = readpfm(fname); + +figure(2); +nvv = size(nv,2); +for j=1:min(5,nvv-1), + subplot(1,min(5,nvv-1),j); + ims(nv(:,j+1),nr,nc); +end + + +%figure(5); +%subplot(2,2,1);plot(eigval(:,1),'x-'); + + +if 0, + +fname = 130039; +for j=0:20, + cm = sprintf('!cp plaatje_data/%d_%d.pfm plaatje_data/test_%d.pfm ',fname,j,j); + disp(cm);eval(cm); +end + +%%%%%%%% +fnout = 'test';fn_t = '334003'; +cm = sprintf('!cp plaatje_data/%s_eigval.pfm %s_eigval.pfm',fnout,fn_t); +disp(cm);eval(cm); +cm = sprintf('!cp plaatje_data/%s_eigvec.pfm %s_eigvec.pfm',fnout,fn_t); +disp(cm);eval(cm); +cm = sprintf('!cp plaatje_data/%s_ncutvec.pfm %s_ncutvec.pfm',fnout,fn_t); +disp(cm);eval(cm); +cm = sprintf('!cp plaatje_data/%s_ncutval.pfm %s_ncutval.pfm',fnout,fn_t); +disp(cm);eval(cm); + + + + +end + +disp_flag = 0; +if disp_flag, + [I1,bnr,bnc] = proj_back_id(ncutv(:,2),gcs,gce,grs,gre); + imvs(I,I1>0.002,bnr,bnc); +end + +if 0, + + nv = 3; + A = eigv(:,1:nv)*eigv(:,1:nv)'; + [v,d] = ncut(abs(A),min(nv,5)); + + figure(3); + for j=1:min(nv,5), + subplot(2,2,j); + ims(v(:,j),nr,nc); + end + +end + +%%%%%%%% + +figure(4);%im(I);colorbar; +hw = 3;st_sz = 2*hw+1; +ct = round(ginput(1)); +ct_chank(1) = round((ct(1)-hw-1)/st_sz) + 1; +ct_chank(2) = round((ct(2)-hw-1)/st_sz) + 1; + +idx = (ct_chank(:,1)-1)*nr + ct_chank(:,2); + +figure(5);im(abs(reshape(A(idx,:),nr,nc)));%colorbar; + + + + %%%%% + + fname = 'test2'; + fn = sprintf('plaatje_data/ncut_%s.pfm',fname); + ncutv1 = readpfm(fn); + nr = 30; nc=49; + + figure(1); + for j=1:min(4,size(ncutv1,2)), + subplot(2,2,j); + ims(ncutv1(:,j+1),nr,nc); + end + + + +%%%%%%%%%% + + id = 0; + fn = sprintf('plaatje_data/test_Aa%d.pfm',id); + disp(sprintf('A = readpfm(%s);',fn)); + A = readpfm(fn); + + cm = sprintf('[v%d,d%d] = eigs(A,12);',id,id); + disp(cm);eval(cm); + + writepfm('test_eigv0.pfm',v0); + writepfm('test_eigva0.pfm',diag(d0)); + + + + +vs = zeros(size(v1,1),size(v1,2),6); +ds = zeros(length(d1),6); + +for j=0:5, + cm = sprintf('vs(:,:,%d) = v%d;',j+1,j); + disp(cm);eval(cm); + cm = sprintf('d = diag(d%d);',j); + disp(cm);eval(cm); + cm = sprintf('ds(:,%d) = d(:);',j+1); + disp(cm);eval(cm); + + +end + +%save evsum vs ds + +figure(1);nr = 49;nc=30;evid = 3; +for j=1:12,subplot(3,4,j);ims(vs(:,j,evid),nr,nc);end + +I = readpgm('images/334039.pgm');I = cutoff(I,20); + +As = zeros(6,nr*nc); + +figure(3);%im(I);colormap(gray); +hw = 3;st_sz = 2*hw+1; +ct = round(ginput(1));ct_chank(1) = round((ct(1)-hw-1)/st_sz) + 1;ct_chank(2) = round((ct(2)-hw-1)/st_sz) + 1; +idx = (ct_chank(:,1)-1)*nr + ct_chank(:,2); + +figure(5); + +figure(4);nvs = [6,9,12,12,12,12]; +for evid = 1:5,As(evid,:) = squeeze(vs(idx,1:nvs(evid),evid))*squeeze(vs(:,1:nvs(evid),evid))';end +for evid =1:5,subplot(2,3,evid);im(abs(reshape(As(evid,:),nr,nc)));colorbar;end +subplot(2,3,6);ims(sum(abs(As)),nr,nc);colorbar + +%%%%%%%%% + +%%%%%% eig of the As over all scales %% + +A = zeros(nr*nc,nr*nc); + +for evid=1:5, disp(evid); + A = A + abs(squeeze(vs(:,1:nvs(evid),evid))*squeeze(vs(:,1:nvs(evid),evid))'); +end + +[v,d] = eigs(A,12); +figure(1); for j=1:12, subplot(3,4,j);ims(v(:,j),nr,nc);end + +[vn,dn] = ncut_b(A,12); +figure(3); for j=1:12, subplot(3,4,j);ims(-vn(:,j),nr,nc);end + +nv = 6; +A = abs(eigv(:,1:nv)*eigv(:,1:nv)'); +[v,d] = ncut_b(A,nv+1); +figure(1); +nv = 4; +for j=1:nv,subplot(2,nv,j);ims(v(:,j+1),nr,nc);title(sprintf('%3.3e',d(j+1)));end + +for j=1:nv,subplot(2,nv,j+nv);ims(eigv(:,j),nr,nc);title(sprintf('%3.3e',eigval(j,1)));end + +%%%%%%%%%%%%% + +while 1, +figure(3);%im(I);colormap(gray); +hw = 3;st_sz = 2*hw+1; +ct = round(ginput(1));ct_chank(1) = round((ct(1)-hw-1)/st_sz) + 1;ct_chank(2) = round((ct(2)-hw-1)/st_sz) + 1; +idx = (ct_chank(:,1)-1)*nr + ct_chank(:,2); + +figure(1); +ims(exp(-(A(idx,:))/(0.02^2)),nr,nc);colorbar +end + + + +%%%%%%%%%%%%%% + +figure(3); +hw = 3;st_sz = 2*hw+1; +np = 20; +ct = round(ginput(np)); +ct_chank =[]; +ct_chank(:,1) = round((ct(:,1)-hw-1)/st_sz) + 1; +ct_chank(:,2) = round((ct(:,2)-hw-1)/st_sz) + 1; +idx = (ct_chank(:,1)-1)*nr + ct_chank(:,2); + +%As = readpfm_id('plaatje_data/130040_AX.pfm',idx,2924); +As = readpfm_idf('plaatje_data/tmp/134035_AX3.pfm',idx,nr*nc); + +%save dist_data2 As idx ct_chank ct hw nr nc eigv eigval + +%load dist_data1a + +set(gcf,'DefaultLineLinewidth',5); + +minA = min(min(As)); +figure(1);clf; hold off; +set(gcf,'DefaultLineLinewidth',2); +for id = 1:np, +subplot(4,5,id); +%image(2.8e-2*((-minA)+reshape(As(id,:),nr,nc)));axis('image');axis('off');hold on +ims(-As(id,:),nr,nc);axis('off');hold on +plot(ct_chank(id,1)+1,ct_chank(id,2)+1,'rx');hold off; +end + +figure(1);clf;hold off; +nvv = 6 +set(gcf,'DefaultLineLinewidth',1); +for id=1:np, + At = abs(eigv(idx(id),1:nvv)*eigv(:,1:nvv)'); + subplot(4,5,id); + %image(2.5e4*reshape(At,nr,nc));axis('image');axis('off');hold on + ims(At,nr,nc);axis('off');hold on; + plot(ct_chank(id,1)+1,ct_chank(id,2)+1,'rx');hold off; +end + + +print_flag =0; +if print_flag, + fn = '130040'; + + figure(4);clf; + colormap(gray); + set(gcf,'DefaultLineLinewidth',7); + + for id =1:np, + %image(2.8e-2*((-minA)+reshape(As(id,:),nr,nc)));axis('image');axis('off');hold on + ims(-As(id,:),nr,nc);axis('off'); + hold on;plot(ct_chank(id,1)+1,ct_chank(id,2)+1,'rp');hold off; + cm = sprintf('print -deps dist_x1_%s_%d',fn,id); + disp(cm);eval(cm); + end + + nvv = 5; + set(gcf,'DefaultLineLinewidth',7); + figure(4);colormap(gray); + for id=1:np, + At = abs(eigv(idx(id),1:nvv)*eigv(:,1:nvv)'); + %image(1.5e4*reshape(At,nr,nc));axis('image');axis('off');%hold on + ims(At,nr,nc);axis('off');%hold on; + %plot(ct_chank(id,1)+1,ct_chank(id,2)+1,'rp');hold off; + cm = sprintf('print -deps dist_d_%s_%d',fn,id); + disp(cm);eval(cm); + end + + % print eigvects + for j=1:size(eigv,2), + ims(eigv(:,j),nr,nc);axis('off'); + cm = sprintf('print -deps eigv_%s_%d',fn,j); + disp(cm);eval(cm); + end + + for j=1:size(ncutv,2), + ims(ncutv(:,j),nr,nc);axis('off'); + cm = sprintf('print -deps ncutv_%s_%d',fn,j); + disp(cm);eval(cm); + end + + +end + +basedir ='plaatje_data/newdata/'; +fname = sprintf('%s%s_eigvec.pfm',basedir,fn); +eigv = readpfm(fname); + +ix = 1; +figure(5);colormap(gray);clf +for j=1:7, + for k=[2,3,4,6,9,12]; + subplot(7,6,ix); + At = abs(eigv(idx(j),1:k)*eigv(:,1:k)'); + ims(At,nr,nc);axis('off');%colorbar; + if (k==2), + hold on; plot(ct_chank(j,1),ct_chank(j,2),'rp');hold off; + title(num2str(j)); + end + ix = ix+1; + end +end + +figure(4);clf;colormap(gray); +set(gcf,'DefaultLineLinewidth',7); +for j=1:20, + for k=[2,3,4,6,9,12]; + + At = abs(eigv(idx(j),1:k)*eigv(:,1:k)'); + ims(At,nr,nc);axis('off');%colorbar; + if (k==2), + hold on; plot(ct_chank(j,1),ct_chank(j,2),'rp');hold off; + end + + cm = sprintf('print -deps dist_scale_65_%d_%d',j,k); + disp(cm);eval(cm); + + end +end + +base_dir = 'plaatje_data/'; + +% cts are the centers, + +wz = [hw,hw]; +gap = 2*hw+1; +dist = zeros(size(cts,1),(nr+1)*(nc+1)); + +for j=1:1:24, + fn = sprintf('%s134035_%d.pfm',base_dir,j); + disp(fn); + F = readpfm(fn); + + dists = compute_Lf(F,cts,wz,nr,nc); + dist = max(dists,dist); + +end + + +figure(4);clf;colormap(gray); +set(gcf,'DefaultLineLinewidth',7); + +ids = [8,1,12,5,10,15]; + +for j=1:6, + + d = reshape(dist(j,:),nr+1,nc+1); + d = d(1:end-1,2:end); + im(-d);axis('off'); hold on; + plot(ct_chank(ids(j),1),ct_chank(ids(j),2),'p'); + hold off + + cm = sprintf('print -deps dist_lf_65_%d',j); + disp(cm);eval(cm); + + pause; +end + + + +end + + diff --git a/SD-VBS/common/toolbox/toolbox_basic/filter_hist/disp_evresult2.m b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/disp_evresult2.m new file mode 100755 index 0000000..46239ef --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/disp_evresult2.m @@ -0,0 +1,215 @@ +fn = '130042'; + +fname = sprintf('data/%s_eigvec.pfm',fn); +eigv = readpfm(fname); +fname = sprintf('data/%s_eigval.pfm',fn); +eigval = readpfm(fname); + +fname = sprintf('data/%s_ncutvec.pfm',fn); +ncutv = readpfm(fname); +fname = sprintf('data/%s_ncutval.pfm',fn); +ncutval = readpfm(fname); + +%fname = sprintf('images/130038.pgm'); +fname = sprintf('images/%s.pgm',fn); +I = readpgm(fname); +cutsz = 20; I = cutoff(I,cutsz); +figure(3);im(I);colormap(gray); + +new = 0; + +if new, + fn1 = fn; + fn = 'test'; + fname = sprintf('data/%s_gcs.pfm',fn); + gcs = readpfm(fname); + + fname = sprintf('data/%s_gce.pfm',fn); + gce = readpfm(fname); + + fname = sprintf('data/%s_grs.pfm',fn); + grs = readpfm(fname); + + fname = sprintf('data/%s_gre.pfm',fn); + gre = readpfm(fname); + + nr = max(gre(:))+1; + nc = max(gce(:))+1; + + fn = fn1; + +else + %nr = 49;nc = 30; + nr = 30;nc = 49; + +end + +figure(6); +for j=1:8, + subplot(3,3,j); + im(reshape(ncutv(:,j+1),nr,nc));colorbar + title(num2str(ncutval(j+1,1))); +end +%cm = sprintf('print -dps ncut_%s',fn);disp(cm);eval(cm); +subplot(3,3,9);im(I);axis('off'); + +figure(7);clf +for j=1:9, + subplot(3,3,j); + im(reshape(eigv(:,j),nr,nc));colorbar;%axis('off'); + title(sprintf('%3.4e',eigval(j,1))); +end +%cm = sprintf('print -dps eig_%s',fn);disp(cm);eval(cm); + + + +if 0, + +fname = 130042; +for j=0:30, + cm = sprintf('!cp plaatje_data/%d_%d.pfm data/%d_%d.pfm ',fname,j,fname,j); + disp(cm);eval(cm); +end + +%%%%%%%% +fnout = '130042';fn_t = '130042'; +cm = sprintf('!cp data/%s_eigval.pfm %s_eigval.pfm',fnout,fn_t); +disp(cm);eval(cm); +cm = sprintf('!cp data/%s_eigvec.pfm %s_eigvec.pfm',fnout,fn_t); +disp(cm);eval(cm); +cm = sprintf('!cp data/%s_ncutvec.pfm %s_ncutvec.pfm',fnout,fn_t); +disp(cm);eval(cm); +cm = sprintf('!cp data/%s_ncutval.pfm %s_ncutval.pfm',fnout,fn_t); +disp(cm);eval(cm); + + + + +end + +disp_flag = 0; +if disp_flag, + [I1,bnr,bnc] = proj_back_id(ncutv(:,2),gcs,gce,grs,gre); + imvs(I,I1>0.002,bnr,bnc); +end + +if 0, + + nv = 3; + A = eigv(:,1:nv)*eigv(:,1:nv)'; + [v,d] = ncut(abs(A),min(nv,5)); + + figure(3); + for j=1:min(nv,5), + subplot(2,2,j); + ims(v(:,j),nr,nc); + end + + +%%%%%%%% + +figure(4);%im(I);colorbar; +hw = 3;st_sz = 2*hw+1; +ct = round(ginput(1)); +ct_chank(1) = round((ct(1)-hw-1)/st_sz) + 1; +ct_chank(2) = round((ct(2)-hw-1)/st_sz) + 1; + +idx = (ct_chank(:,1)-1)*nr + ct_chank(:,2); + +figure(5);im(abs(reshape(A(idx,:),nr,nc)));%colorbar; + + + + %%%%% + + fname = 'test2'; + fn = sprintf('data/ncut_%s.pfm',fname); + ncutv1 = readpfm(fn); + nr = 30; nc=49; + + figure(1); + for j=1:min(4,size(ncutv1,2)), + subplot(2,2,j); + ims(ncutv1(:,j+1),nr,nc); + end + + + +%%%%%%%%%% + + id = 0; + fn = sprintf('data/test_Aa%d.pfm',id); + disp(sprintf('A = readpfm(%s);',fn)); + A = readpfm(fn); + + cm = sprintf('[v%d,d%d] = eigs(A,12);',id,id); + disp(cm);eval(cm); + + writepfm('test_eigv0.pfm',v0); + writepfm('test_eigva0.pfm',diag(d0)); + + + + +vs = zeros(size(v1,1),size(v1,2),6); +ds = zeros(length(d1),6); + +for j=0:5, + cm = sprintf('vs(:,:,%d) = v%d;',j+1,j); + disp(cm);eval(cm); + cm = sprintf('d = diag(d%d);',j); + disp(cm);eval(cm); + cm = sprintf('ds(:,%d) = d(:);',j+1); + disp(cm);eval(cm); + + +end + +%save evsum vs ds + +figure(1);nr = 49;nc=30;evid = 3; +for j=1:12,subplot(3,4,j);ims(vs(:,j,evid),nr,nc);end + +I = readpgm('images/334039.pgm');I = cutoff(I,20); + +As = zeros(6,nr*nc); + +figure(3);%im(I);colormap(gray); +hw = 3;st_sz = 2*hw+1; +ct = round(ginput(1));ct_chank(1) = round((ct(1)-hw-1)/st_sz) + 1;ct_chank(2) = round((ct(2)-hw-1)/st_sz) + 1; +idx = (ct_chank(:,1)-1)*nr + ct_chank(:,2); + +figure(5); + +figure(4);nvs = [6,9,12,12,12,12]; +for evid = 1:5,As(evid,:) = squeeze(vs(idx,1:nvs(evid),evid))*squeeze(vs(:,1:nvs(evid),evid))';end +for evid =1:5,subplot(2,3,evid);im(abs(reshape(As(evid,:),nr,nc)));colorbar;end +subplot(2,3,6);ims(sum(abs(As)),nr,nc);colorbar + +%%%%%%%%% + +%%%%%% eig of the As over all scales %% + +A = zeros(nr*nc,nr*nc); + +for evid=1:5, disp(evid); + A = A + abs(squeeze(vs(:,1:nvs(evid),evid))*squeeze(vs(:,1:nvs(evid),evid))'); +end + +[v,d] = eigs(A,12); +figure(1); for j=1:12, subplot(3,4,j);ims(v(:,j),nr,nc);end + +[vn,dn] = ncut_b(A,12); +figure(3); for j=1:12, subplot(3,4,j);ims(-vn(:,j),nr,nc);end + +nv = 6; +A = abs(eigv(:,1:nv)*eigv(:,1:nv)'); +[v,d] = ncut_b(A,nv+1); +figure(1); +for j=1:nv,subplot(2,nv,j);ims(v(:,j+1),nr,nc);title(sprintf('%3.3e',d(j+1)));end + +for j=1:nv,subplot(2,nv,j+nv);ims(eigv(:,j),nr,nc);title(sprintf('%3.3e',eigval(j,1)));end + + + +end diff --git a/SD-VBS/common/toolbox/toolbox_basic/filter_hist/disp_evresulthome.m b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/disp_evresulthome.m new file mode 100755 index 0000000..208b86a --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/disp_evresulthome.m @@ -0,0 +1,237 @@ +fn = '334003'; + +fname = sprintf('%s_eigvec.pfm',fn); +disp(sprintf('reading %s',fname)); +eigv = readpfm(fname); +fname = sprintf('%s_eigval.pfm',fn); +eigval = readpfm(fname); + +fname = sprintf('%s_ncutvec.pfm',fn); +ncutv = readpfm(fname); +fname = sprintf('%s_ncutval.pfm',fn); +ncutval = readpfm(fname); + +%fname = sprintf('images/130038.pgm'); +fname = sprintf('images/%s.pgm',fn); +I = readpgm(fname); +cutsz = 20; I = cutoff(I,cutsz); +figure(3);im(I);colormap(gray); + +new = 0; + +if new, + fn1 = fn; + fn = 'test'; + fname = sprintf('%s_gcs.pfm',fn); + gcs = readpfm(fname); + + fname = sprintf('%s_gce.pfm',fn); + gce = readpfm(fname); + + fname = sprintf('%s_grs.pfm',fn); + grs = readpfm(fname); + + fname = sprintf('%s_gre.pfm',fn); + gre = readpfm(fname); + + nr = max(gre(:))+1; + nc = max(gce(:))+1; + + fn = fn1; + +else + nr = 49;nc = 30; + %nr = 30;nc = 49; + +end + +figure(6); +for j=1:8, + subplot(3,3,j); + im(reshape(ncutv(:,j+1),nr,nc));colorbar + title(num2str(ncutval(j+1,1))); +end +%cm = sprintf('print -dps ncut_%s',fn);disp(cm);eval(cm); +%subplot(3,3,9);im(I);axis('off'); + +figure(7);clf +for j=1:9, + subplot(3,3,j); + im(reshape(eigv(:,j),nr,nc));colorbar;%axis('off'); + title(sprintf('%3.4e',eigval(j,1))); +end +%cm = sprintf('print -dps eig_%s',fn);disp(cm);eval(cm); + + + +if 0, + +fname = 130042; +for j=0:30, + cm = sprintf('!cp plaatje_data/%d_%d.pfm data/%d_%d.pfm ',fname,j,fname,j); + disp(cm);eval(cm); +end + +%%%%%%%% +fnout = '130042';fn_t = '130042'; +cm = sprintf('!cp data/%s_eigval.pfm %s_eigval.pfm',fnout,fn_t); +disp(cm);eval(cm); +cm = sprintf('!cp data/%s_eigvec.pfm %s_eigvec.pfm',fnout,fn_t); +disp(cm);eval(cm); +cm = sprintf('!cp data/%s_ncutvec.pfm %s_ncutvec.pfm',fnout,fn_t); +disp(cm);eval(cm); +cm = sprintf('!cp data/%s_ncutval.pfm %s_ncutval.pfm',fnout,fn_t); +disp(cm);eval(cm); + + + + +end + +disp_flag = 0; +if disp_flag, + [I1,bnr,bnc] = proj_back_id(ncutv(:,2),gcs,gce,grs,gre); + imvs(I,I1>0.002,bnr,bnc); +end + +if 0, + + nv = 3; + A = eigv(:,1:nv)*eigv(:,1:nv)'; + [v,d] = ncut(abs(A),min(nv,5)); + + figure(3); + for j=1:min(nv,5), + subplot(2,2,j); + ims(v(:,j),nr,nc); + end + + +%%%%%%%% + +figure(4);%im(I);colorbar; +hw = 3;st_sz = 2*hw+1; +ct = round(ginput(1)); +ct_chank(1) = round((ct(1)-hw-1)/st_sz) + 1; +ct_chank(2) = round((ct(2)-hw-1)/st_sz) + 1; + +idx = (ct_chank(:,1)-1)*nr + ct_chank(:,2); + +figure(5);im(abs(reshape(A(idx,:),nr,nc)));%colorbar; + + + + %%%%% + + fname = 'test2'; + fn = sprintf('data/ncut_%s.pfm',fname); + ncutv1 = readpfm(fn); + nr = 30; nc=49; + + figure(1); + for j=1:min(4,size(ncutv1,2)), + subplot(2,2,j); + ims(ncutv1(:,j+1),nr,nc); + end + + + +%%%%%%%%%% + + id = 0; + fn = sprintf('test_Aa%d.pfm',id); + disp(sprintf('A = readpfm(%s);',fn)); + A = readpfm(fn); + + cm = sprintf('[v%d,d%d] = eigs(A,12);',id,id); + disp(cm);eval(cm); + + writepfm('test_eigv0.pfm',v0); + writepfm('test_eigva0.pfm',diag(d0)); + + + + +vs = zeros(size(v1,1),size(v1,2),6); +ds = zeros(length(d1),6); + +for j=0:5, + cm = sprintf('vs(:,:,%d) = v%d;',j+1,j); + disp(cm);eval(cm); + cm = sprintf('d = diag(d%d);',j); + disp(cm);eval(cm); + cm = sprintf('ds(:,%d) = d(:);',j+1); + disp(cm);eval(cm); + + +end + +%save evsum vs ds + +figure(1);nr = 49;nc=30;evid = 3; +for j=1:12,subplot(3,4,j);ims(vs(:,j,evid),nr,nc);end + +I = readpgm('images/334039.pgm');I = cutoff(I,20); + +As = zeros(6,nr*nc); + +figure(3);%im(I);colormap(gray); +hw = 3;st_sz = 2*hw+1; +ct = round(ginput(1));ct_chank(1) = round((ct(1)-hw-1)/st_sz) + 1;ct_chank(2) = round((ct(2)-hw-1)/st_sz) + 1; +idx = (ct_chank(:,1)-1)*nr + ct_chank(:,2); + +figure(5); + +figure(4);nvs = [6,9,12,12,12,12]; +for evid = 1:5,As(evid,:) = squeeze(vs(idx,1:nvs(evid),evid))*squeeze(vs(:,1:nvs(evid),evid))';end +for evid =1:5,subplot(2,3,evid);im(abs(reshape(As(evid,:),nr,nc)));colorbar;end +subplot(2,3,6);ims(sum(abs(As)),nr,nc);colorbar + +%%%%%%%%% + +%%%%%% eig of the As over all scales %% + +A = zeros(nr*nc,nr*nc); + +for evid=1:5, disp(evid); + A = A + abs(squeeze(vs(:,1:nvs(evid),evid))*squeeze(vs(:,1:nvs(evid),evid))'); +end + +[v,d] = eigs(A,12); +figure(1); for j=1:12, subplot(3,4,j);ims(v(:,j),nr,nc);end + +[vn,dn] = ncut_b(A,12); +figure(3); for j=1:12, subplot(3,4,j);ims(-vn(:,j),nr,nc);end + +nv = 6; +A = abs(eigv(:,1:nv)*eigv(:,1:nv)'); +[v,d] = ncut_b(A,nv+1); +figure(1); +for j=1:nv,subplot(2,nv,j);ims(v(:,j+1),nr,nc);title(sprintf('%3.3e',d(j+1)));end + +for j=1:nv,subplot(2,nv,j+nv);ims(eigv(:,j),nr,nc);title(sprintf('%3.3e',eigval(j,1)));end + +%%%%%%%%%%%%%%%%% + +while 1, +figure(3);%im(I);colormap(gray); +hw = 3;st_sz = 2*hw+1; +ct = round(ginput(1));ct_chank(1) = round((ct(1)-hw-1)/st_sz) + 1;ct_chank(2) = round((ct(2)-hw-1)/st_sz) + 1; +idx = (ct_chank(:,1)-1)*nr + ct_chank(:,2); + +figure(1); +ims(exp(-(A(idx,:))/(0.03^2)),nr,nc);colorbar +end + +disp_evresulthome; +close(3);close(7);close(6); +A = euclid_dist(ncutv(:,2:6)); +A = exp(-A/(0.05^2)); + +[v,d] = eigs(A,9); + +figure(2); +for j=1:9,subplot(3,3,j);ims(v(:,j),nr,nc);colorbar;end + + +end diff --git a/SD-VBS/common/toolbox/toolbox_basic/filter_hist/disp_groups.m b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/disp_groups.m new file mode 100755 index 0000000..d087218 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/disp_groups.m @@ -0,0 +1,13 @@ +function disp_groups(groups,ids,nr,nc); + +np = ids(end); + +baseid =1; +for j=1:length(ids), + mask = zeros(np,1); + mask(groups(baseid:ids(j))) = 1+mask(groups(baseid:ids(j))); + + subplot(3,3,j); + ims(mask,nr,nc); + baseid = 1+ids(j); +end diff --git a/SD-VBS/common/toolbox/toolbox_basic/filter_hist/disp_hist2d.m b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/disp_hist2d.m new file mode 100755 index 0000000..4313234 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/disp_hist2d.m @@ -0,0 +1,15 @@ +function H2 = disp_hist2d(J,Jf,scales,filter_ids) + +ns = length(scales); +nf = length(filter_ids); + +H2 = []; +for j=1:ns, + for k=1:nf, + subplot(ns,nf,(j-1)*nf+k); + H2d = hist_I_f(J,Jf(:,:,filter_ids(k),scales(j))); + imagesc(H2d);axis('image');axis('off');drawnow; + H2(:,:,j,k) = H2d; + end +end + diff --git a/SD-VBS/common/toolbox/toolbox_basic/filter_hist/dist_pair.m b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/dist_pair.m new file mode 100755 index 0000000..1c7b2cf --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/dist_pair.m @@ -0,0 +1,28 @@ +function d = dist_pair(idx,fv,hb) +% (hb=sigs,bin_mins,bin_maxs,nbins) +% +% +% computes the pairwise distance between +% a point and everyone else using histogram binized feature +% + + +[nf,np] = size(fv); + +d = zeros(1,np); +nbins = [0,hb.nbins]; + + +for j=1:nf, + bin_min = hb.bmins(j); + bin_max = hb.bmaxs(j); + nbin = nbins(j+1); + sig = hb.sigs(j); + fprintf(sprintf('|%d',j)); + b = binize(fv(j,:),sig,bin_min,bin_max,nbin); + + a = binize(fv(j,idx),sig,bin_min,bin_max,nbin); + + d = d + a'*b; +end +fprintf('\n'); diff --git a/SD-VBS/common/toolbox/toolbox_basic/filter_hist/dist_pair_chank.m b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/dist_pair_chank.m new file mode 100755 index 0000000..96a0d60 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/dist_pair_chank.m @@ -0,0 +1,25 @@ +function d = dist_pair_chank(a,fvs,chank_size) +% (hb=sigs,bin_mins,bin_maxs,nbins) +% +% +% computes the pairwise distance between +% a point and everyone else using histogram binized feature +% + + +[nf,np] = size(fvs); + +n_chanks = ceil(np/chank_size); + +d = []; +for j=1:n_chanks, + fprintf('<'); + + cm = sprintf('load st_%d',j); + eval(cm); + fprintf(sprintf('%d',n_chanks-j)); + + d = [d,a*fh]; +end + +fprintf('\n'); diff --git a/SD-VBS/common/toolbox/toolbox_basic/filter_hist/doog2.m b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/doog2.m new file mode 100755 index 0000000..3ec22c1 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/doog2.m @@ -0,0 +1,43 @@ +function [G]=doog2(sig,r,th,N); +% [G,H]=doog2(sig,r,th,N); +% Make difference of offset gaussians kernel +% theta is in degrees +% (see Malik & Perona, J. Opt. Soc. Amer., 1990) +% +% Example: +% >> imagesc(-doog2(.5,4,15,32)) +% >> colormap(gray) + +% by Serge Belongie + +no_pts=N; % no. of points in x,y grid +pad_pts=no_pts*sqrt(2); % pad grid dimensions for up to a 45 degree rotation +siz=6; % range of x,y grid + +[x,y]=meshgrid(linspace(-siz,siz,pad_pts),linspace(-siz,siz,pad_pts)); + +a=-1; +b=2; +c=-1; + +ya=sig; +yc=-ya; +yb=0; +sigy=sig; +sigx=r*sig; + +Ga=(1/(2*pi*sigx*sigy))*exp(-(((x-0)/sigx).^2+((y-ya)/sigy).^2)); +Gb=(1/(2*pi*sigx*sigy))*exp(-(((x-0)/sigx).^2+((y-yb)/sigy).^2)); +Gc=(1/(2*pi*sigx*sigy))*exp(-(((x-0)/sigx).^2+((y-yc)/sigy).^2)); + +Go = a*Ga + b*Gb + c*Gc; +%Ho = imag(hilbert(Go)); +G = Go; + +G = mimrotate(Go,th,'bilinear','crop'); +G = imcrop(G,[(pad_pts-no_pts)/2, (pad_pts-no_pts)/2, no_pts, no_pts]); + +%H = imrotate(Ho,th,'bilinear','crop'); +%H = imcrop(H,[(pad_pts-no_pts)/2, (pad_pts-no_pts)/2, no_pts, no_pts]); + + diff --git a/SD-VBS/common/toolbox/toolbox_basic/filter_hist/eig_decomp.m b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/eig_decomp.m new file mode 100755 index 0000000..5209088 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/eig_decomp.m @@ -0,0 +1,15 @@ +function [v,d] = eig_decomp(A) + +ds = sum(A); +ds = ones(size(ds))./sqrt(ds); +D1 = ds'*ones(1,length(ds)); +A = D1'.*A.*D1; + +disp(sprintf('computing eig values')); +tic;[v,d] = eig(A);toc; + +d = abs(diag(d)); +[tmp,idx] = sort(-d); +d = d(idx); +v = v(:,idx); +v = D1.*v; diff --git a/SD-VBS/common/toolbox/toolbox_basic/filter_hist/eig_decomp_v5.m b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/eig_decomp_v5.m new file mode 100755 index 0000000..e0fab2c --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/eig_decomp_v5.m @@ -0,0 +1,13 @@ +function [v,d] = eig_decomp_v5(A,nv) + +ds = sum(A); +ds = ones(size(ds))./sqrt(ds); +D1 = ds'*ones(1,length(ds)); +A = D1'.*A.*D1; + +disp(sprintf('computing eig values')); +tic;[v,d] = eigs(A,nv);toc; + +d = abs(diag(d)); + +v = D1(:,1:size(v,2)).*v; diff --git a/SD-VBS/common/toolbox/toolbox_basic/filter_hist/eig_proj.m b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/eig_proj.m new file mode 100755 index 0000000..78d5296 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/eig_proj.m @@ -0,0 +1,12 @@ +function v = eig_proj(u,data) + +% fd = feature dimension, nv = num. of eigvectors +[fd,nv] = size(u); + +[fd2,nd] = size(data); + +if (fd ~= fd2), + error(sprintf('size don't match')); +else + v = data'*u; +end diff --git a/SD-VBS/common/toolbox/toolbox_basic/filter_hist/eigs_decomp.m b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/eigs_decomp.m new file mode 100755 index 0000000..7763124 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/eigs_decomp.m @@ -0,0 +1,39 @@ +function [v,d,D,Ipara] = eigs_decomp(fn,num_eigs) +% +% function [v,d,D,Ipara] = eigs_decomp(fn,num_eigs) +% + +%fn = '2.ppm'; +fn = 'images/130049.pgm'; + + +% spatial gaussian parameter +xscale = 3; + +% half size of the neighbourhood +xnb = 6; + +% setting the the HSV gaussian parameter:[h s v] +Iscale = [0.008,0.01,0.01]; + +Input_para = [xscale,xnb,Iscale]; + +% compute the lower half the association matrix +[A,D,Ipara] = compute_A_ppm(fn,Input_para); + +B = A+A'; +clear A; + +% eigen decompostion +options.tol = 1e-7; +num_eig_v = 4; +fprintf('doing eigs ...\n'); +[v,d] = eigs(B,num_eig_v,options); + +d = diag(d); + +% to display the final result + +%nr = Ipara(1);nc = Ipara(2); +%k = 1;imagesc(reshape(v(:,k).*D,nc,nr)');colorbar + diff --git a/SD-VBS/common/toolbox/toolbox_basic/filter_hist/euclid_dist.m b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/euclid_dist.m new file mode 100755 index 0000000..cbf0734 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/euclid_dist.m @@ -0,0 +1,22 @@ +function [A,mag] = euclid_dist(v) + + + +A = 2*v*v'; + +nv = size(v,2); +if (nv>1) + mag = sum((v.*v)')'; +else + mag = v.*v; +end + +np = length(mag); + +for j=1:np, + A(:,j) = mag-A(:,j); +end + +for j=1:np, + A(j,:) = mag' + A(j,:); +end diff --git a/SD-VBS/common/toolbox/toolbox_basic/filter_hist/filter_all_files.m b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/filter_all_files.m new file mode 100755 index 0000000..c1752e5 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/filter_all_files.m @@ -0,0 +1,29 @@ +sigs = [1/sqrt(2),1,sqrt(2),2,2*sqrt(2)];r = 3;szs = round(r*3*sigs); + +load filenames; + +nfiles = size(filename,1); + +for j = 48:nfiles, + fname = ['images/',filename(j,:)]; + fname + I = readpgm(fname); + + text_des = compute_filter(I,sigs,r,szs); + + data_name = sprintf('filter_%s.mat',filename(j,:)); + cm = sprintf('save %s ',data_name); + + disp(cm); + eval(cm); + clear; + + sigs = [1/sqrt(2),1,sqrt(2),2,2*sqrt(2)];r = 3;szs = round(r*3*sigs); + + load filenames; + + nfiles = size(filename,1); + + +end + diff --git a/SD-VBS/common/toolbox/toolbox_basic/filter_hist/filter_output.m b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/filter_output.m new file mode 100755 index 0000000..a489c6e --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/filter_output.m @@ -0,0 +1,38 @@ +function If = filter_output(I,sigs,szs,flag); +% +% compute filter output for all orientation and scale, +% + +%% flag = 1 if compute oriented filter output +if (~exist('flag')), + flag = 1; +end + + +If = []; + +for j = 1:length(sigs), + sig = sigs(j); + sz = 2*round(4*sig)+1; + + g = mkdog1(sig,sz); + fprintf('['); + fprintf('.'); + If(:,:,1,j) = conv2(I,g,'same'); + + angles = [0:30:150]; + r = 3; + + if flag, + for k = 1:length(angles), + fprintf('.'); + g = mdoog2(sig,r,angles(k),szs(j)); + If(:,:,k+1,j) = conv2(I,g,'same'); + end + end + + fprintf(']'); + +end + +fprintf('\n'); \ No newline at end of file diff --git a/SD-VBS/common/toolbox/toolbox_basic/filter_hist/find_bst_cut.m b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/find_bst_cut.m new file mode 100755 index 0000000..c85cc2b --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/find_bst_cut.m @@ -0,0 +1,24 @@ +function [cut_threshold,max_asso] = find_bst_cut(fn_base,para,threshold,Gmask) + +basedir = 'plaatje_data/'; +%basedir = './'; + +fn = sprintf('%sbst_cut.tex',basedir); +write_command(fn,fn_base,para); + +fn= sprintf('%sthreshold_%s.pfm',basedir,fn_base); +writepfm(fn,threshold(:)); + +fn= sprintf('%sGmask_%s.pfm',basedir,fn_base); +writepfm(fn,Gmask(:)); + +cd plaatje_data +!./find_bestcut +cd /home/barad-dur/vision/malik/jshi/proj/grouping/texture + +fn = sprintf('%sbst_asso_%s.pfm',basedir,fn_base); +results = readpfm(fn); +asso = results(1,:); +[max_asso,id] = max(asso); +cut_threshold = threshold(id); + diff --git a/SD-VBS/common/toolbox/toolbox_basic/filter_hist/find_center.m b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/find_center.m new file mode 100755 index 0000000..b5a127a --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/find_center.m @@ -0,0 +1,4 @@ +function [center_x,center_y] = find_center(size_x,size_y); + +center_x = 0.5*(size_x -1)+1; +center_y = 0.5*(size_y -1)+1; diff --git a/SD-VBS/common/toolbox/toolbox_basic/filter_hist/find_cutpoint.m b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/find_cutpoint.m new file mode 100755 index 0000000..5cab956 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/find_cutpoint.m @@ -0,0 +1,13 @@ +function [cutpoints,x] = find_cutpoint(data,cmap,nbin) +% +% [cutpoints,x] = find_cutpoint(data,cmap,nbin) +% +% + +x = id_cut(data,cmap,nbin); + +cutpoints = zeros(1,nbin); + +for j=1:nbin, + cutpoints(j) = max(data(x<=j)); +end diff --git a/SD-VBS/common/toolbox/toolbox_basic/filter_hist/gen_filters.m b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/gen_filters.m new file mode 100755 index 0000000..65e3c3a --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/gen_filters.m @@ -0,0 +1,47 @@ +function filters = gen_filters(sig,r,sz); + + +as = 0:30:150; + +filters = []; + +if size(sig,2)== 1, + + for j = 1:length(as), + fprintf('.'); + angle = as(j); + + g = mdoog2(sig,r,angle,round(sz)); + + g = g - mean(reshape(g,prod(size(g)),1)); + + g = g/sum(sum(abs(g))); + + filters(:,:,j) = g; + end +else + + % there are multiple scales + sigs = sig; + szs = sz; + for k = 1:size(sigs,2), + sig = sigs(k); + sz = szs(length(szs)-1); + fprintf('%d',k); + for j = 1:length(as), + fprintf('.'); + angle = as(j); + + g = mdoog2(sig,r,angle,round(sz)); + g = g - mean(reshape(g,prod(size(g)),1)); + g = g/sum(sum(abs(g))); + + filters(:,:,j,k) = g; + end + + + end + +end + +fprintf('\n'); diff --git a/SD-VBS/common/toolbox/toolbox_basic/filter_hist/get_cumhist.m b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/get_cumhist.m new file mode 100755 index 0000000..b05d680 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/get_cumhist.m @@ -0,0 +1,9 @@ +function cumhists = get_cumhist(hists) +% +% +% cumhists = get_cumhist(hists) +% + +cumhists.inten = cumsum(hists.inten)/sum(hists.inten); +cumhists.text = cumsum(hists.text,1)./(ones(size(hists.text,1),1)*sum(hists.text,1)); +cumhists.mag = cumsum(hists.mag)/sum(hists.mag); \ No newline at end of file diff --git a/SD-VBS/common/toolbox/toolbox_basic/filter_hist/get_cumhist_inten.m b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/get_cumhist_inten.m new file mode 100755 index 0000000..911b4e6 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/get_cumhist_inten.m @@ -0,0 +1,7 @@ +function CH_inten = get_cumhist(hists) +% +% +% cumhists = get_cumhist(hists) +% + +CH_inten = cumsum(hists)/sum(hists); diff --git a/SD-VBS/common/toolbox/toolbox_basic/filter_hist/get_hist.m b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/get_hist.m new file mode 100755 index 0000000..d480a3a --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/get_hist.m @@ -0,0 +1,24 @@ +function [hists,bins] = get_hists(J,Jbar) +% +% +% produce histogram output of the image J and its +% filter outputs Jbar +% + +maxval = 60; +bin = [1:4:maxval+1]; + +w = size(J); + + +[hists.inten,bins.inten] = hist(reshape(J,prod(w),1),[1:26:256]); + +for j=1:size(Jbar,3), + hists.text(:,j) = hist(reshape(abs(Jbar(:,:,j)),prod(w),1),bin); +end + +bins.text = bin; + +[hists.mag,bins.mag] = hist(reshape(sum(abs(Jbar),3),prod(w),1),[1:10:161]); + + diff --git a/SD-VBS/common/toolbox/toolbox_basic/filter_hist/get_hist_inten.m b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/get_hist_inten.m new file mode 100755 index 0000000..c8357c6 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/get_hist_inten.m @@ -0,0 +1,15 @@ +function [Hinten,Hbins] = get_hists_inten(J,nbin) +% +% +% produce histogram output of the image J and its +% filter outputs Jbar +% + + +w = size(J); + +[Hinten,Hbins] = hist(reshape(J,prod(w),1),linspace(1,256,nbin)); + + + + diff --git a/SD-VBS/common/toolbox/toolbox_basic/filter_hist/get_win.m b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/get_win.m new file mode 100755 index 0000000..411a694 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/get_win.m @@ -0,0 +1,10 @@ +function J = get_win(I,center,wc) +% +% J = get_win(I,center,wc) +% +% center: [x,y] + + + +J = I(center(2)-wc(2):center(2)+wc(2),... + center(1)-wc(1):center(1)+wc(1)); diff --git a/SD-VBS/common/toolbox/toolbox_basic/filter_hist/get_win5.m b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/get_win5.m new file mode 100755 index 0000000..e8404e5 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/get_win5.m @@ -0,0 +1,11 @@ +function J = get_win5(I,center,wc) +% +% J = get_win5(I,center,wc) +% +% center: [x,y] + + + +J = I(center(2)-wc(2):center(2)+wc(2),... + center(1)-wc(1):center(1)+wc(1),:,:); + diff --git a/SD-VBS/common/toolbox/toolbox_basic/filter_hist/grad.m b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/grad.m new file mode 100755 index 0000000..6da0fbf --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/grad.m @@ -0,0 +1,24 @@ +% gradient of an image +% coordinates (r, c) follow matrix convention; +% the gaussian is truncated at x = +- tail, and there are samples samples +% inbetween, where samples = hsamples * 2 + 1 + +function[gr,gc] = gradient(image, hsamples) + +tail=4; +samples = hsamples * 2 + 1; + +x = linspace(-tail, tail, samples); +gauss = exp(-x.^2); +n = gauss * ones(samples,1); +gauss = gauss/n; + +gaussderiv = -x.*gauss; +n = -gaussderiv*linspace(1,samples,samples)'; +gaussderiv = gaussderiv/n; + +gr = conv2(conv2(image, gaussderiv','valid'), gauss,'valid'); +gc = conv2(conv2(image, gaussderiv,'valid'), gauss','valid'); + +%gr = conv_trim(gr, hsamples, hsamples); +%gc = conv_trim(gc, hsamples, hsamples); diff --git a/SD-VBS/common/toolbox/toolbox_basic/filter_hist/half_sigmoid.m b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/half_sigmoid.m new file mode 100755 index 0000000..c187b6c --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/half_sigmoid.m @@ -0,0 +1,17 @@ +function a = half_sigmoid(x,offset,sig) +% +% a = half_sigmoid(x,offset,sig) +% +% a = ones(size(x))./(1+exp(-(x-offset)/sig)); +% +% keep the sign of a + +sign_x = sign(x); +x = abs(x); + +a = ones(size(x))./(1+exp(-(x-offset)/sig)); + +off = 1/(1+exp(-(0-offset)/sig)); + +a = sign_x.*(a-off); + diff --git a/SD-VBS/common/toolbox/toolbox_basic/filter_hist/hist2d.m b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/hist2d.m new file mode 100755 index 0000000..3f4db0c --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/hist2d.m @@ -0,0 +1,13 @@ +function H2 = hist2d(J,Jf,scales,filter_ids) + +ns = length(scales); +nf = length(filter_ids); + +H2 = []; +for j=1:ns, + for k=1:nf, + H2d = hist_I_f(J,Jf(:,:,filter_ids(k),scales(j))); + H2(:,:,j,k) = H2d; + end +end + diff --git a/SD-VBS/common/toolbox/toolbox_basic/filter_hist/hist_I_f.m b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/hist_I_f.m new file mode 100755 index 0000000..a993661 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/hist_I_f.m @@ -0,0 +1,22 @@ +function h2d = hist_I_f(I,If,binI,binf) + +if (nargin == 2), + binI = [0:13:260]; + binf = [-30:2.5*2:30]; +end + +%%% make 2d histogram bin +h2d = []; + +for j = 2:length(binf), + + [id_i,id_j] = find((If>binf(j-1)) & (If<=binf(j))); + if (length(id_i) >0), + h = hist(I(id_i+(id_j-1)*size(I,1)),binI); + else + h = zeros(size(binI)); + end + + h2d = [h2d,h']; +end + diff --git a/SD-VBS/common/toolbox/toolbox_basic/filter_hist/hist_diff.m b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/hist_diff.m new file mode 100755 index 0000000..6976c8f --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/hist_diff.m @@ -0,0 +1,30 @@ +function hdiff = hist_diff(H1,H2) +% +% hdiff = hist_diff(H1,H2) +% + +ns = size(H1,3); +nf = size(H1,4); + +sI= [1,0,1];sI = exp(-sI); +sI = sI/sum(sI); + +hdiff = 0; +for j = 1:ns, + for k = 1:nf, + h1 = H1(:,:,j,k); + h2 = H2(:,:,j,k); + + h1s = conv2(conv2(h1,sI','same'),sI,'same'); + h2s = conv2(conv2(h2,sI','same'),sI,'same'); + + [is,js] = find( (h1>0) | (h2>0)); + ids = (js-1)*size(h1,1) + is; + + xdiffs = ((h1s(ids)-h2s(ids)).*(h1s(ids)-h2s(ids)))./(h1s(ids)+h2s(ids)); + hdiff = hdiff + sum(xdiffs); + + end +end + +hdiff = hdiff/(ns*nf); diff --git a/SD-VBS/common/toolbox/toolbox_basic/filter_hist/hist_f.m b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/hist_f.m new file mode 100755 index 0000000..93f50a9 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/hist_f.m @@ -0,0 +1,28 @@ +function h2d = hist_f(Ifs,f1,s1,f2,s2) + + +binf = [-30:2.5*2:30]; + + +%%% make 2d histogram bin + +If1 = Ifs(:,:,f1,s1); +If2 = Ifs(:,:,f2,s2); +h2d = []; + +binf(1) = -100; +binf(length(binf)) = 100; + +for j = 2:length(binf), + + [id_i,id_j] = find((If1>binf(j-1)) & (If1<=binf(j))); + if (length(id_i) >0), + + h = hist(If2(id_i+(id_j-1)*size(If2,1)),binf); + else + h = zeros(size(binf)); + end + + + h2d = [h2d,h']; +end diff --git a/SD-VBS/common/toolbox/toolbox_basic/filter_hist/hist_in_chank.m b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/hist_in_chank.m new file mode 100755 index 0000000..74661b2 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/hist_in_chank.m @@ -0,0 +1,33 @@ +function covfh = hist_inner_chank(fv,chank_size,nbin) +% fh = hist_inner_chank(fv,hb,chank_file) +% +% (hb = bin_mins,bin_maxs,nbins) +% +% take which histogram value and turn it into histogram bin +% compute the inner product of the histogram bin features +% + +[nf,np] = size(fv); + +tbins = nf*nbin; +disp(sprintf('need matrix of %d x %d ',tbins,tbins)); + +covfh = zeros(tbins,tbins); + +n_chanks = ceil(np/chank_size); +for j=1:n_chanks, + fprintf('<'); + + cm = sprintf('load st_%d',j); + eval(cm); + fprintf(sprintf('%d',n_chanks-j)); + + %ms = mean(fh'); + %fh = fh- ms'*ones(1,size(fh,2)); + + covfh = covfh + fh*fh'; + fprintf('>'); +end + +fprintf('\n'); + diff --git a/SD-VBS/common/toolbox/toolbox_basic/filter_hist/hist_inner.m b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/hist_inner.m new file mode 100755 index 0000000..6fd02b7 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/hist_inner.m @@ -0,0 +1,40 @@ +function fh = hist_inner(fv,hb) +% (hb = bin_mins,bin_maxs,nbins) +% +% take which histogram value and turn it into histogram bin +% compute the inner product of the histogram bin features +% + +[nf,np] = size(fv); + +nbins = [0,hb.nbins]; + +disp(sprintf('need matrix of %d x %d ',sum(nbins),sum(nbins))); + +fh = zeros(sum(nbins),sum(nbins)); + +for j=1:nf, + bin_min = hb.bmins(j); + bin_max = hb.bmaxs(j); + nbin = nbins(j+1); + sig = hb.sigs(j); + fprintf('|'); + b0 = binize(fv(j,:),sig,bin_min,bin_max,nbin); + + fh(sum(nbins(1:j))+1:sum(nbins(1:j+1)),sum(nbins(1:j))+1:sum(nbins(1:j+1))) = b0*b0'; + + for k=j+1:nf, + bin_min = hb.bmins(k); + bin_max = hb.bmaxs(k); + nbin = nbins(k+1); + sig = hb.sigs(k); + fprintf('.'); + b = binize(fv(k,:),sig,bin_min,bin_max,nbin); + tmp = b0*b'; + + fh(sum(nbins(1:j))+1:sum(nbins(1:j+1)),sum(nbins(1:k))+1:sum(nbins(1:k+1))) = tmp; + fh(sum(nbins(1:k))+1:sum(nbins(1:k+1)),sum(nbins(1:j))+1:sum(nbins(1:j+1))) = tmp'; + end +end + +fprintf('\n'); diff --git a/SD-VBS/common/toolbox/toolbox_basic/filter_hist/histbin_fv_chank.m b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/histbin_fv_chank.m new file mode 100755 index 0000000..8cf2a35 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/histbin_fv_chank.m @@ -0,0 +1,14 @@ +function histbin_fv_chank(fvs,hb,chank_size,fname_base) + +[nv,np] = size(fvs); + +k =1; +for j=1:chank_size:np, + disp(sprintf('|%d',j)); + fh = colize_hist(fvs(:,j:min(j+chank_size-1,np)),hb); + fname = sprintf('%s_%d.mat',fname_base,k); + cm = sprintf('save %s fh hb;',fname); + disp(cm); + eval(cm); + k = k+1; +end diff --git a/SD-VBS/common/toolbox/toolbox_basic/filter_hist/hsv2clrs.m b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/hsv2clrs.m new file mode 100755 index 0000000..cfbb8b0 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/hsv2clrs.m @@ -0,0 +1,25 @@ +function [x,y,z] = hsv2clrs(h,s,v) +% +% function [x,y,z] = hsv2clrs(h,s,v) +% if h is 3D matrix, output in 3D x +% + +if (size(h,3) == 3), + s = h(:,:,2); + v = h(:,:,3); + h = h(:,:,1); + + z = v; + xx = s.*v.*cos(2*pi*h); + y = s.*v.*sin(2*pi*h); + + x(:,:,1) = xx; + x(:,:,2) = y; + x(:,:,3) = z; +else + + z = v; + x = s.*v.*cos(2*pi*h); + y = s.*v.*sin(2*pi*h); +end + diff --git a/SD-VBS/common/toolbox/toolbox_basic/filter_hist/id_cut.m b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/id_cut.m new file mode 100755 index 0000000..daf8f2b --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/id_cut.m @@ -0,0 +1,14 @@ +function [x,map] = idcut(data,cmap,nbin) +% +% +% + +lc = size(cmap,1); + +data = data - min(data); +data = 1+ ((lc-1)*data/max(data)); + +r = cmap(data,1);g = cmap(data,2);b = cmap(data,3); + +[x,map] = vmquant(r,g,b,nbin); + diff --git a/SD-VBS/common/toolbox/toolbox_basic/filter_hist/im.m b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/im.m new file mode 100755 index 0000000..6450120 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/im.m @@ -0,0 +1,3 @@ +function im(I) + +imagesc(I);axis('image');drawnow; \ No newline at end of file diff --git a/SD-VBS/common/toolbox/toolbox_basic/filter_hist/im3.m b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/im3.m new file mode 100755 index 0000000..b49e690 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/im3.m @@ -0,0 +1,3 @@ +function im3(d) + +imagesc(reshape(d,size(d,1),size(d,2)*size(d,3))); diff --git a/SD-VBS/common/toolbox/toolbox_basic/filter_hist/im5.m b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/im5.m new file mode 100755 index 0000000..7f1b16d --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/im5.m @@ -0,0 +1,16 @@ +function im5(data,nr,nc,mag) + +if nargin == 4, +for j=1:size(data,3), + subplot(nr,nc,j); + imagesc(data(:,:,j)./mag);axis('image');axis('off');colorbar;drawnow; + +% image(150*data(:,:,j));axis('image');axis('off');colorbar;drawnow; +end + +else +for j=1:size(data,3), + subplot(nr,nc,j); + imagesc(data(:,:,j));axis('image');axis('off');colorbar;drawnow; +end +end diff --git a/SD-VBS/common/toolbox/toolbox_basic/filter_hist/im_vect.m b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/im_vect.m new file mode 100755 index 0000000..d0a5b30 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/im_vect.m @@ -0,0 +1,20 @@ +function a = im_vect(loca,v,scale); + +if ~exist('scale'), + scale = 50; +end + +y = loca(1,:); +x = loca(2,:); + +x = x - min(x); +y = y - min(y); + +max_x = max(x);max_y = max(y); +min_scale = min(max_x,max_y); + +x = scale*x/min_scale; +y = scale*y/min_scale; + + +a = sparse(y+1,x+1,v); diff --git a/SD-VBS/common/toolbox/toolbox_basic/filter_hist/imrotate.m b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/imrotate.m new file mode 100755 index 0000000..167fd02 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/imrotate.m @@ -0,0 +1,119 @@ +function bout = imrotate(arg1,arg2,arg3,arg4) +%IMROTATE Rotate image. +% B = IMROTATE(A,ANGLE,'method') rotates the image A by ANGLE +% degrees. The image returned B will, in general, be larger +% than A. Invalid values on the periphery are set to one +% for indexed images or zero for all other image types. Possible +% interpolation methods are 'nearest','bilinear' or 'bicubic'. +% 'bilinear' is the default for intensity images, otherwise +% 'nearest' is used if no method is given. +% +% B = IMROTATE(A,ANGLE,'crop') or IMROTATE(A,ANGLE,'method','crop') +% crops B to be the same size as A. +% +% Without output arguments, IMROTATE(...) displays the rotated +% image in the current axis. +% +% See also IMRESIZE, IMCROP, ROT90. + +% Clay M. Thompson 8-4-92 +% Copyright (c) 1992 by The MathWorks, Inc. +% $Revision: 1.14 $ $Date: 1993/09/01 21:27:38 $ + +if nargin<2, error('Requires at least two input parameters.'); end +if nargin<3, + if isgray(arg1), caseid = 'bil'; else caseid = 'nea'; end + docrop = 0; +elseif nargin==3, + if isstr(arg3), + method = [lower(arg3),' ']; % Protect against short method + caseid = method(1:3); + if caseid(1)=='c', % Crop string + if isgray(arg1), caseid = 'bil'; else caseid = 'nea'; end + docrop = 1; + else + docrop = 0; + end + else + error('''METHOD'' must be a string of at least three characters.'); + end +else + if isstr(arg3), + method = [lower(arg3),' ']; % Protect against short method + caseid = method(1:3); + else + error('''METHOD'' must be a string of at least three characters.'); + end + docrop = 1; +end + +% Catch and speed up 90 degree rotations +if rem(arg2,90)==0 & nargin<4, + phi = rem(arg2,360); + if phi==90, + b = rot90(arg1); + elseif phi==180, + b = rot90(arg1,2); + elseif phi==270, + b = rot90(arg1,-1); + else + b = arg1; + end + if nargout==0, imshow(b), else bout = b; end + return +end + +phi = arg2*pi/180; % Convert to radians + +% Rotation matrix +T = [cos(phi) -sin(phi); sin(phi) cos(phi)]; + +% Coordinates from center of A +[m,n] = size(arg1); +if ~docrop, % Determine limits for rotated image + siz = ceil(max(abs([(n-1)/2 -(m-1)/2;(n-1)/2 (m-1)/2]*T))/2)*2; + uu = -siz(1):siz(1); vv = -siz(2):siz(2); +else % Cropped image + uu = (1:n)-(n+1)/2; vv = (1:m)-(m+1)/2; +end +nu = length(uu); nv = length(vv); + +blk = bestblk([nv nu]); +nblks = floor([nv nu]./blk); nrem = [nv nu] - nblks.*blk; +mblocks = nblks(1); nblocks = nblks(2); +mb = blk(1); nb = blk(2); + +rows = 1:blk(1); b = zeros(nv,nu); +for i=0:mblocks, + if i==mblocks, rows = (1:nrem(1)); end + for j=0:nblocks, + if j==0, cols = 1:blk(2); elseif j==nblocks, cols=(1:nrem(2)); end + if ~isempty(rows) & ~isempty(cols) + [u,v] = meshgrid(uu(j*nb+cols),vv(i*mb+rows)); + % Rotate points + uv = [u(:) v(:)]*T'; % Rotate points + u(:) = uv(:,1)+(n+1)/2; v(:) = uv(:,2)+(m+1)/2; + if caseid(1)=='n', % Nearest neighbor interpolation + b(i*mb+rows,j*nb+cols) = interp6(arg1,u,v); + elseif all(caseid=='bil'), % Bilinear interpolation + b(i*mb+rows,j*nb+cols) = interp4(arg1,u,v); + elseif all(caseid=='bic'), % Bicubic interpolation + b(i*mb+rows,j*nb+cols) = interp5(arg1,u,v); + else + error(['Unknown interpolation method: ',method]); + end + end + end +end + +d = find(isnan(b)); +if length(d)>0, + if isind(arg1), b(d) = ones(size(d)); else b(d) = zeros(size(d)); end +end + +if nargout==0, + imshow(b), return +end +bout = b; + + diff --git a/SD-VBS/common/toolbox/toolbox_basic/filter_hist/ims.m b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/ims.m new file mode 100755 index 0000000..2fb5f25 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/ims.m @@ -0,0 +1,3 @@ +function ims(I,nr,nc) + +im(reshape(I,nr,nc)); \ No newline at end of file diff --git a/SD-VBS/common/toolbox/toolbox_basic/filter_hist/imvs.m b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/imvs.m new file mode 100755 index 0000000..21dde73 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/imvs.m @@ -0,0 +1,4 @@ +function imvs(I,v,nr,nc) + +v = reshape(v,nr,nc); +im(I(1:size(v,1),1:size(v,2)).*v); \ No newline at end of file diff --git a/SD-VBS/common/toolbox/toolbox_basic/filter_hist/is_step.m b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/is_step.m new file mode 100755 index 0000000..4903778 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/is_step.m @@ -0,0 +1,33 @@ +function P_step = is_step(gx,gy) +% +% P_step = is_step(gx,gy) +% +% determine wheter gx,gy(which is first +% order filter output) is a response +% to a step function +% + +M = zeros(2,2); +M(1,1) = sum(sum(gx.*gx)); +M(2,2) = sum(sum(gy.*gy)); +M(1,2) = sum(sum(gx.*gy)); +M(2,1) = M(1,2); + +[v,d] = eig(M); +d = diag(d); + +% make the first eig_value to be the smaller one +if (d(2)< d(1)), + tmp = d(1);d(1) = d(2);d(2) = tmp; + tmp = v(:,1); v(:,1) = v(:,2); v(:,2) = tmp; +end + +ratio = d(1)/d(2); +threshold = 0; +gx_ratio = sum(sum(gx.*(gx>threshold)))/(sum(sum(abs(gx).*(abs(gx)>threshold)))); +gx_ratio = max(gx_ratio,1-gx_ratio); + +gy_ratio = sum(sum(gy.*(gy>threshold)))/(sum(sum(abs(gy).*(abs(gy)>threshold)))); +gy_ratio = max(gy_ratio,1-gy_ratio); + +P_step = [ratio,gx_ratio,gy_ratio]; diff --git a/SD-VBS/common/toolbox/toolbox_basic/filter_hist/ks_2d.m b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/ks_2d.m new file mode 100755 index 0000000..cfac005 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/ks_2d.m @@ -0,0 +1,20 @@ +function [na,nb,nc,nd] = ks_2d(cum_filter) + +[nb_filters,nb_bins] = size(cum_filter); + +T = 1; + +for j = [1:nb_filters], + for l = [1:nb_bins], + nc(j,l) = sum(cum_filter(1:j,l)); + nd(j,l) = j*T - nc(j,l); + + if (j~= nb_filters), + nb(j,l) = sum(cum_filter(j+1:nb_filters,l)); + na(j,l) = (nb_filters-j)*T-nb(j,l); + else + nb(j,l) = 0; + na(j,l) = 0; + end + end +end diff --git a/SD-VBS/common/toolbox/toolbox_basic/filter_hist/load_result.m b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/load_result.m new file mode 100755 index 0000000..0ff328c --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/load_result.m @@ -0,0 +1,39 @@ + +fnameI = '130056'; + +cm = sprintf('load filter_%s.pgm.mat',fnameI); +disp(cm); +eval(cm); + +text_des= reshape(text_des,size(text_des,1),size(text_des,2),size(text_des,3)*size(text_des,4)); + +for j=1:size(text_des,3), + text_des(:,:,j) = abs(text_des(:,:,j)).*(text_des(:,:,j) <0); +end + +%text_des = abs(text_des); + + + %%%% cutoff margins, +margin = 6+10; + +Iw = cutoff(I,margin); + + +T1 = cutoff(text_des,margin); + +%%%%% reduce resolution + + + +T1 = reduce_all(T1); +T1 = reduce_all(T1); + +im5(T1,5,6); + +cm = sprintf('writepnm5(''%s_f.pnm'',%s)',fnameI,'T1/70'); + +% disp(cm);eval(cm); + +nr = size(T1,1); +nc = size(T1,2); diff --git a/SD-VBS/common/toolbox/toolbox_basic/filter_hist/m_interp4.m b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/m_interp4.m new file mode 100755 index 0000000..314f140 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/m_interp4.m @@ -0,0 +1,49 @@ +function [F,mask] = m_interp4(z,s,t) +%INTERP4 2-D bilinear data interpolation. +% ZI = INTERP4(Z,XI,YI) assumes X = 1:N and Y = 1:M, where +% [M,N] = SIZE(Z). +% +% Copyright (c) 1984-93 by The MathWorks, Inc. +% Clay M. Thompson 4-26-91, revised 7-3-91, 3-22-93 by CMT. +% +% modified to + + +[nrows,ncols] = size(z); + + +if any(size(z)<[3 3]), error('Z must be at least 3-by-3.'); end +if size(s)~=size(t), error('XI and YI must be the same size.'); end + +% Check for out of range values of s and set to 1 +sout = find((s<1)|(s>ncols)); +if length(sout)>0, s(sout) = ones(size(sout)); end + +% Check for out of range values of t and set to 1 +tout = find((t<1)|(t>nrows)); +if length(tout)>0, t(tout) = ones(size(tout)); end + +% Matrix element indexing +ndx = floor(t)+floor(s-1)*nrows; + +% Compute intepolation parameters, check for boundary value. +d = find(s==ncols); +s(:) = (s - floor(s)); +if length(d)>0, s(d) = s(d)+1; ndx(d) = ndx(d)-nrows; end + +% Compute intepolation parameters, check for boundary value. +d = find(t==nrows); +t(:) = (t - floor(t)); +if length(d)>0, t(d) = t(d)+1; ndx(d) = ndx(d)-1; end +d = []; + +% Now interpolate, reuse u and v to save memory. +F = ( z(ndx).*(1-t) + z(ndx+1).*t ).*(1-s) + ... + ( z(ndx+nrows).*(1-t) + z(ndx+(nrows+1)).*t ).*s; + +mask = ones(size(z)); + +% Now set out of range values to zeros. +if length(sout)>0, F(sout) = zeros(size(sout));mask(sout)=zeros(size(sout));end +if length(tout)>0, F(tout) = zeros(size(tout));mask(tout)=zeros(size(tout));end + diff --git a/SD-VBS/common/toolbox/toolbox_basic/filter_hist/make_masks.m b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/make_masks.m new file mode 100755 index 0000000..d2c8ba7 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/make_masks.m @@ -0,0 +1,12 @@ +function masks = make_masks(groups,ids,nr,nc); + +np = ids(end); + +baseid =1; +for j=1:length(ids), + mask = zeros(np,1); + mask(groups(baseid:ids(j))) = 1+mask(groups(baseid:ids(j))); + baseid = 1+ids(j); + + masks(:,:,j) = mask; +end diff --git a/SD-VBS/common/toolbox/toolbox_basic/filter_hist/makefilter.m b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/makefilter.m new file mode 100755 index 0000000..a768269 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/makefilter.m @@ -0,0 +1,14 @@ +function H = make_filter(txture,sze,noise) +% function H = make_filter(txture,sze) +% +% + +x = zeros(sze); +tx_sze = size(txture); + +x(1:tx_sze(1),1:tx_sze(2)) = txture; +x = reshape(x,1,sze(1)*sze(2)); +X = fft(x); +figure(3);plot(abs(X).^2); + +H = X./(abs(X).^2+noise); diff --git a/SD-VBS/common/toolbox/toolbox_basic/filter_hist/mkf_t1.m b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/mkf_t1.m new file mode 100755 index 0000000..256e609 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/mkf_t1.m @@ -0,0 +1,22 @@ +function [H,h] = make_filter(txture,sze,noise) +% function H = make_filter(txture,sze) +% +% + +tx_sze = size(txture); +x = reshape(txture,1,tx_sze(1)*tx_sze(2)); +X = fft(x); +H = X./(abs(X).^2+noise); +h = reshape(real(ifft(H)),tx_sze(1),tx_sze(2)); + + +x = zeros(sze); +x(1:tx_sze(1),1:tx_sze(2)) = h; +figure(1);imagesc(x);drawnow; +x = reshape(x,1,sze(1)*sze(2)); +H = fft(x); + +h = reshape(real(ifft(H)),sze(1),sze(2)); +figure(2);imagesc(h); + +figure(3); mesh(h); \ No newline at end of file diff --git a/SD-VBS/common/toolbox/toolbox_basic/filter_hist/mkf_t2.m b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/mkf_t2.m new file mode 100755 index 0000000..c84482d --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/mkf_t2.m @@ -0,0 +1,21 @@ +function [H,h] = make_filter(txture,sze,noise) +% function H = make_filter(txture,sze) +% +% + +x = zeros(sze); +tx_sze = size(txture); + +[center_x,center_y] = find_center(sze(2),sze(1)); +tx_sze_h = round(0.5*tx_sze); + +x(center_y-tx_sze_h(1):center_y-tx_sze_h(1)+tx_sze(1)-1,... + center_x-tx_sze_h(2):center_x-tx_sze_h(2)+tx_sze(2)-1) = txture; +figure(1);imagesc(x);drawnow; +x = reshape(x,1,sze(1)*sze(2)); +X = fft(x); +H = X./(abs(X).^2+noise); +h = reshape(real(ifft(H)),sze(1),sze(2)); +figure(2);imagesc(h); + +figure(3); mesh(h); \ No newline at end of file diff --git a/SD-VBS/common/toolbox/toolbox_basic/filter_hist/mkf_test.m b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/mkf_test.m new file mode 100755 index 0000000..e8d0ad8 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/mkf_test.m @@ -0,0 +1,43 @@ +function [H,h] = make_filter(txture,sze,n_c,a,b,c) +% function H = make_filter(txture,sze) +% +% + +x = zeros(sze); +tx_sze = size(txture); + +x(1:tx_sze(1),1:tx_sze(2)) = txture; +%figure(1);imagesc(x);drawnow; +x = reshape(x,1,sze(1)*sze(2)); +X = fft(x); +power = abs(X).^2; + +figure(3);plot(power); +len = length(X); + +t = [1:0.5*(length(X)-1),0.5*(length(X)-1):-1:1]; + +top = max(power); +if (c == -1), + c = top*5.0e-1 +end +if (n_c == -1), + n_c = top*1.0e-1 +end + +nois = n_c +c*(exp(-a*(t.^b))); +if (rem(len,2) == 1), + noise = [c+n_c,nois]; +else + noise = [c+n_c,nois,c+n_c]; +end + +figure(3);hold on;plot(noise,'r'); +hold off +H = X./(abs(X).^2+noise); +h = reshape(real(ifft(H)),sze(1),sze(2)); +figure(2);imagesc(h); + +figure(4);plot(abs(H).^2,'c') +%figure(3); mesh(h); + diff --git a/SD-VBS/common/toolbox/toolbox_basic/filter_hist/mkg.m b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/mkg.m new file mode 100755 index 0000000..1fb1f7e --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/mkg.m @@ -0,0 +1,9 @@ +function g= mkgaussian(xo,yo,sigma_x,sigma_y,size_w) +% +% function G = mkgaussian(xo,yo,sigma_x,sigma_y,size_w) +% + +size_wh = round(0.5*size_w); +[x,y] = meshgrid([-size_wh:1:size_wh],[-size_wh:1:size_wh]); +g = 1/(2*pi*sigma_x*sigma_y)*(exp(-( ((x-xo)/sigma_x).^2 + ((y-yo)/sigma_y).^2))); + diff --git a/SD-VBS/common/toolbox/toolbox_basic/filter_hist/mkgaussian.m b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/mkgaussian.m new file mode 100755 index 0000000..1213757 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/mkgaussian.m @@ -0,0 +1,11 @@ +function G = mkgaussian(xo,yo,sigma_x,sigma_y,size_w) +% +% function G = mkgaussian(xo,yo,sigma_x,sigma_y,size_w) +% + +size_wh = round(0.5*size_w); + +[x,y] = meshgrid([-size_wh:1:size_wh],[-size_wh:1:size_wh]); + +G = 0.5/(sigma_x*sigma_y)*(exp(-( ((x-xo)/sigma_x).^2 + ((y-yo)/sigma).^2))); + diff --git a/SD-VBS/common/toolbox/toolbox_basic/filter_hist/mkmulfilter.m b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/mkmulfilter.m new file mode 100755 index 0000000..fe501b5 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/mkmulfilter.m @@ -0,0 +1,52 @@ +function H = make_multi_filter(templates,num_templates,sze,u,noise) +% function H = make_filter(templates,num_templates,sze,u,noise) +% templates are column vectors of template +% sze is the size of the filter +% u is a vector of specified value +% +% + +templates_size_x = size(templates,2)/num_templates; +templates_size_y = size(templates,1); + +alpha = 1/num_templates; + +X = zeros(num_templates,sze(1)*sze(2)); +Spectrums = zeros(num_templates,sze(1)*sze(2)); + + +for k =1:num_templates, + tmp = zeros(sze); + tmp(1:templates_size_y,1:templates_size_x) =... + templates(:,(k-1)*templates_size_x+1:k*templates_size_x); + x(k,:) = reshape(tmp,1,sze(1)*sze(2)); + X(k,:) = fft(x(k,:)); + Spectrums(k,:) = conj(X(k,:)).*X(k,:); +end + +if num_templates > 1 + sum_Spect = sum(Spectrums)*alpha; +else + sum_Spect = Spectrums; +end + +for row = 1:num_templates, + for column = 1:num_templates, + + A(row,column) = sum( ((conj(X(row,:)).*X(column,:))./... + (sum_Spect + noise))')/(sze(1)*sze(2)); + end +end + + +epsilon = inv(A)*u; + +top = epsilon(1)*X(1,:); +for k = 2:num_templates, + top = top + epsilon(k)*X(k,:); +end + +H = top./(sum_Spect + noise); + + + diff --git a/SD-VBS/common/toolbox/toolbox_basic/filter_hist/mkpoog2.m b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/mkpoog2.m new file mode 100755 index 0000000..4bd0366 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/mkpoog2.m @@ -0,0 +1,29 @@ +function doog2 = mkdoog2(sigma_w,r,theta,size_w) +% +% function doog2 = mkdoog2(sigma_w,r,theta,size_w) +% +% + +%scale_base = 2.8814; +scale_base = 2; + +a = -1*scale_base; +b = 2*scale_base; +c = -1*scale_base; + +sigma_x = r*sigma_w; +sigma_y = sigma_w; + +ya = sigma_w; +yc = -sigma_w; +yb = 0; + +doog2 = a*mkg(0,ya,sigma_x,sigma_y,size_w) +... + b*mkg(0,yb,sigma_x,sigma_y,size_w) +... + c*mkg(0,yc,sigma_x,sigma_y,size_w); + +figure(3);colormap(hsv); +subplot(1,3,1);mesh(a*mkg(0,ya,sigma_x,sigma_y,size_w)); +subplot(1,3,2);mesh(b*mkg(0,yb,sigma_x,sigma_y,size_w)); +subplot(1,3,3);mesh(c*mkg(0,yc,sigma_x,sigma_y,size_w)); +%doog2 = 255*5.1745*doog2; diff --git a/SD-VBS/common/toolbox/toolbox_basic/filter_hist/mksgn.m b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/mksgn.m new file mode 100755 index 0000000..15f947b --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/mksgn.m @@ -0,0 +1,10 @@ +function sgn = makesgn(sigma,sigma_x,sze) + + +size_wh = round(0.5*sze); +[x,y] = meshgrid([-size_wh:1:size_wh],[-size_wh:1:size_wh]); +steps = 1/(1+2*sigma_x); + +fx = -1*(x<=-sigma_x) + (x>=sigma_x) + steps*((x+sigma_x).*(x>-sigma_x).*(x-sigma_x).*(x<1)) + steps*(sigma_x-x).*(x=1); +sgn = fx.*(exp(- (y.*y)/(2*sigma))); \ No newline at end of file diff --git a/SD-VBS/common/toolbox/toolbox_basic/filter_hist/mreadpfm.m b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/mreadpfm.m new file mode 100755 index 0000000..cf68a01 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/mreadpfm.m @@ -0,0 +1,11 @@ +function I = read_pfm(filename) + +fid = fopen(filename,'r'); + +A = fscanf(fid,'%d',2) +I = fscanf(fid,'%f',[A(1),A(2)]); + + +I = I'; +size(I); +fclose(fid); diff --git a/SD-VBS/common/toolbox/toolbox_basic/filter_hist/mreadpfm2.m b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/mreadpfm2.m new file mode 100755 index 0000000..c01b25b --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/mreadpfm2.m @@ -0,0 +1,9 @@ +function I = read_pfm(filename) + +fid = fopen(filename,'r'); + +A = fscanf(fid,'%d',2) +I = fscanf(fid,'%f',[A(1),A(2)]); + + +fclose(fid); diff --git a/SD-VBS/common/toolbox/toolbox_basic/filter_hist/mwis.m b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/mwis.m new file mode 100755 index 0000000..95de8f6 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/mwis.m @@ -0,0 +1,16 @@ +function [l1,l2,phi] = mwis(gx,gy) +% +% [l1,l2,phi] = mwis(gx,gy) +% +% + +sgx = sum(sum(gx.*gx)); +sgxy = sum(sum(gx.*gy)); +sgy = sum(sum(gy.*gy)); + +tr = sgx + sgy; +v1 = 0.5*sqrt(tr*tr - 4*(sgx*sgy-sgxy*sgxy)); +l1 = real(0.5*tr+v1); +l2 = real(0.5*tr-v1); + +phi= 0.5*atan2(2*sgxy,sgx-sgy); diff --git a/SD-VBS/common/toolbox/toolbox_basic/filter_hist/mwis_image.m b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/mwis_image.m new file mode 100755 index 0000000..c8e8b66 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/mwis_image.m @@ -0,0 +1,25 @@ +function [l1,l2,phi] = mwis_image(gx,gy,hs) +% +% [l1,l2,phi] = mwis_image(gx,gy) +% +% + +if (~exist('hs')), + hs = 10; +end + + +sgx = gx.*gx; +sgxy = gx.*gy; +sgy = gy.*gy; + +ssgx = smooth(sgx,hs); +ssgxy = smooth(sgxy,hs); +ssgy = smooth(sgy,hs); + +tr = ssgx + ssgy; +v1 = 0.5*sqrt(tr.*tr - 4*(ssgx.*ssgy-ssgxy.*ssgxy)); +l1 = real(0.5*tr+v1); +l2 = real(0.5*tr-v1); + +phi= 0.5*atan2(2*sgxy,sgx-sgy); diff --git a/SD-VBS/common/toolbox/toolbox_basic/filter_hist/myinterp.m b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/myinterp.m new file mode 100755 index 0000000..6d8f055 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/myinterp.m @@ -0,0 +1,18 @@ +function y = myinterp(d,rate) +% + + +if (size(d,1)>1), + d = [d;d(1)]; +else + d = [d,d(1)]; +end + +lgn = length(d); + +x = 1:lgn; +xx = linspace(1,lgn,rate*lgn); + +y = interp1(x,d,xx,'linear'); + +y = y(1:(length(y)-1)); diff --git a/SD-VBS/common/toolbox/toolbox_basic/filter_hist/ncut_b.m b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/ncut_b.m new file mode 100755 index 0000000..c9eee35 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/ncut_b.m @@ -0,0 +1,25 @@ +function [v,d] = ncut(A,nv) + +ds = sum(A); +ds = ones(size(ds))./sqrt(ds); + +for j=1:size(A,1), + A(j,:) = A(j,:).*ds; +end + +for j=1:size(A,2); + A(:,j) = A(:,j).*ds'; +end + +%D1 = ds'*ones(1,length(ds)); +%A = D1'.*A.*D1; + +disp(sprintf('computing eig values')); +tic;[v,d] = eigs(A,nv);toc; + +d = abs(diag(d)); + +for j=1:nv, + v(:,j) = v(:,j).*ds'; +end +%v = D1(:,1:size(v,2)).*v; diff --git a/SD-VBS/common/toolbox/toolbox_basic/filter_hist/new_compute_J.m b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/new_compute_J.m new file mode 100755 index 0000000..f4e376a --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/new_compute_J.m @@ -0,0 +1,32 @@ +function [JJ,mask] = compute_J(A,D,I,center,window_size_h) +%% function J = compute_J(A,D,I,center,window_size_h) +% + +[size_y,size_x] = size(I); + +center_x = center(1); +center_y = center(2); + +XX = meshgrid(1:size_x,1:size_y); +YY = meshgrid(1:size_y,1:size_x)'; +x = reshape(XX,size_x*size_y,1); +y = reshape(YY,size_x*size_y,1); +index(:,1) = x-center_x; +index(:,2) = y-center_y; + +position_new = A*index'+ [D(1),0;0,D(2)]*ones(2,size_x*size_y); +position_new(1,:) = position_new(1,:)+center_x; +position_new(2,:) = position_new(2,:)+center_y; + +position_new_x = reshape(position_new(1,:),size_y,size_x); +position_new_y = reshape(position_new(2,:),size_y,size_x); + +[J,mask]= m_interp4(I,position_new_x,position_new_y); + +JJ = J(center(2)-window_size_h(2):center(2)+window_size_h(2),... + center(1)-window_size_h(1):center(1)+window_size_h(1)); +mask = mask(center(2)-window_size_h(2):center(2)+window_size_h(2),... + center(1)-window_size_h(1):center(1)+window_size_h(1)); + + + diff --git a/SD-VBS/common/toolbox/toolbox_basic/filter_hist/pair_dist.m b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/pair_dist.m new file mode 100755 index 0000000..f8dbd32 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/pair_dist.m @@ -0,0 +1,45 @@ +function A = apply_image(gx,gy,I,wc) +% +% aout = apply_image(gx,gy,wc) +% +% + +[nr,nc] =size(gx); + +w = 2*wc+1; + +s1 = floor(nr/w); +s2 = floor(nc/w); + +A = zeros(s1*s2,s1*s2); + +yid = 0; +for j=wc+1:w:nr-wc-1, + yid = yid+1; + xid = 0; + for k=wc+1:w:nc-wc-1, + xid = xid + 1; + c1 = [k,j]; + + yyid = 0; + fprintf('.'); + for jj=wc+1:w:nr-wc-1, + yyid = yyid+1; + xxid = 0; + for kk=wc+1:w:nc-wc-1, + xxid = xxid + 1; + + c2 = [kk,jj]; + + a = compute_diff_patch(get_win(gx,c1,[wc,wc]),... + get_win(gy,c1,[wc,wc]),... + get_win(gx,c2,[wc,wc]),... + get_win(gy,c2,[wc,wc]),... + get_win(I,c1,[wc,wc]),... + get_win(I,c2,[wc,wc])); + + A(yid+(xid-1)*s1,yyid+(xxid-1)*s1) = a; + end + end + end +end diff --git a/SD-VBS/common/toolbox/toolbox_basic/filter_hist/pair_dist2.m b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/pair_dist2.m new file mode 100755 index 0000000..dc31469 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/pair_dist2.m @@ -0,0 +1,46 @@ +function A = apply_image(gx,gy,I,wc) +% +% aout = apply_image(gx,gy,wc) +% +% + +[nr,nc] =size(gx); + +w = 2*wc+1; + +lws = 4; + +s1 = floor(nr/w); +s2 = floor(nc/w); + +A = zeros(s1*s2,s1*s2); + +for j=1:s1, + for k=1:s2, + c1 = [(wc+1)+(k-1)*w,(wc+1)+(j-1)*w]; + fprintf('.'); + + for jj=j-lws:j+lws, + for kk=k-lws:k+lws, + + c2 = [(wc+1)+(kk-1)*w,(wc+1)+(jj-1)*w]; + if ( (jj>0) & (kk>0) & (jj <= s1) & (kk <= s2)) + a = compute_diff_patch(get_win(gx,c1,[wc,wc]),... + get_win(gy,c1,[wc,wc]),... + get_win(gx,c2,[wc,wc]),... + get_win(gy,c2,[wc,wc]),... + get_win(I,c1,[wc,wc]),... + get_win(I,c2,[wc,wc])); + + dx = abs(k-kk);dy = abs(j-jj); + sp_diff = exp(-sqrt(dx.^2+dy.^2)/4); + A(j+(k-1)*s1,jj+(kk-1)*s1) = a*sp_diff; + + end + + end + end + end +end + + diff --git a/SD-VBS/common/toolbox/toolbox_basic/filter_hist/pair_dist_text.m b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/pair_dist_text.m new file mode 100755 index 0000000..5cdb201 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/pair_dist_text.m @@ -0,0 +1,70 @@ +function A = apply_image(I,bars,wc) +% +% aout = apply_image(gx,gy,wc) +% +% + +[nr,nc] =size(I); + +w = 2*wc+1; + +lws = 4; + +gap = 10; + +s1 = floor((nr-w)/gap); +s2 = floor((nc-w)/gap); + +A = zeros(s1*s2,s1*s2); + +sigma.text = 0.20; +sigma.mag = 0.20; +sigma.inten = 0.15; + +for j=1:s1, + for k=1:s2, + + + c1 = [(wc+1)+(k-1)*gap,(wc+1)+(j-1)*gap]; + fprintf('.'); + for jj=j-lws:j+lws, + for kk=k-lws:k+lws, + + c2 = [(wc+1)+(kk-1)*gap,(wc+1)+(jj-1)*gap]; + if ( (jj>0) & (kk>0) & (jj <= s1) & (kk <= s2)), + + J1 = get_win(I,c1,[wc,wc]); + J2 = get_win(I,c2,[wc,wc]); + + Jbars1 = get_win5(bars,c1,[wc,wc]); + Jbars2 = get_win5(bars,c2,[wc,wc]); + + + hists1 = get_hist(J1,Jbars1); + hists2 = get_hist(J2,Jbars2); + + cumhists1 = get_cumhist(hists1); + cumhists2 = get_cumhist(hists2); + + + diff.inten = max(abs(cumhists1.inten-cumhists2.inten)); + diff.mag = max(abs(cumhists1.mag-cumhists2.mag)); + diff.text = max(max(abs(cumhists1.text-cumhists2.text))); + + diffs = max([diff.inten/sigma.inten,... + diff.mag/sigma.mag,... + diff.text/sigma.text]); + + dx = abs(k-kk);dy = abs(j-jj); + sp_diff = sqrt(dx.^2+dy.^2)/4; + + A(j+(k-1)*s1,jj+(kk-1)*s1) = exp(-diffs-sp_diff); + + end + + end + end + end +end + + diff --git a/SD-VBS/common/toolbox/toolbox_basic/filter_hist/pair_dist_text2.m b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/pair_dist_text2.m new file mode 100755 index 0000000..5c6e0d4 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/pair_dist_text2.m @@ -0,0 +1,58 @@ +function A = apply_image(I,bars,wc) +% +% aout = apply_image(gx,gy,wc) +% +% + +[nr,nc] =size(I); + +w = 2*wc+1; + +lws = 4; + +gap = 10; + +mag = sum(bars,3); + +s1 = floor((nr-w)/gap) +s2 = floor((nc-w)/gap) + +A = zeros(s1*s2,s1*s2); + +sigma.text = 0.20; +sigma.mag = 0.20; +sigma.inten = 0.15; + +for j=1:s1, + for k=1:s2, + + + c1 = [(wc+1)+(k-1)*gap,(wc+1)+(j-1)*gap]; + fprintf('.'); + for jj=j-lws:j+lws, + for kk=k-lws:k+lws, + + c2 = [(wc+1)+(kk-1)*gap,(wc+1)+(jj-1)*gap]; + if ( (jj>0) & (kk>0) & (jj <= s1) & (kk <= s2)), + + ces = [c1,c2]-wc; + cum = compute_dist_hist(I,mag,bars,[ces,w]); + + diffs = max([cum(1)/sigma.inten,... + cum(2)/sigma.mag,... + cum(3)/sigma.text]); + + dx = abs(k-kk);dy = abs(j-jj); + sp_diff = sqrt(dx.^2+dy.^2)/4; + + A(j+(k-1)*s1,jj+(kk-1)*s1) = exp(-diffs-sp_diff); + + end + + end + end + + end +end + + diff --git a/SD-VBS/common/toolbox/toolbox_basic/filter_hist/pair_dist_text3.m b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/pair_dist_text3.m new file mode 100755 index 0000000..a7ff408 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/pair_dist_text3.m @@ -0,0 +1,84 @@ +function [A,D] = pair_dist_text3(Cum,cumhists) +% +% A = pair_dist_text3(Cum,cumhists); +% +% + +s1 = Cum(2); +s2 = Cum(1); + +st = Cum(3) + Cum(4) + 1; +ed = size(cumhists,1); + +cumhists = cumhists(st:ed,:); + +np = size(cumhists,2); + +sigma.text = 0.20; +sigma.mag = 0.20; +sigma.inten = 0.15; + +lws = 4; + + +k = sqrt(2)/2; +M = 8*6; +N = k*sqrt(M); + +r1 = 0.001; +r2 = 0.001; + +c = N/(1+ (sqrt(1-0.5*(r1*r1+r2*r2)))*(0.25-0.75/N)); + +D = zeros(1,s1*s2); + +nn = 1; +for j =1:s1, + for k=1:s2, + + id = j*s2+k; + + cum_filter1 = reshape(cumhists(:,id),8,6)'; + [na1,nb1,nc1,nd1] = ks_2d(cum_filter1); + + + fprintf('.'); + for jj=j-lws:j+lws, + for kk=k-lws:k+lws, + + if ( (jj>0) & (kk>0) & (jj <= s1) & (kk <= s2)), + + idn = jj*s2+k; + + cum_filter2 = reshape(cumhists(:,idn),8,6)'; + [na2,nb2,nc2,nd2] = ks_2d(cum_filter2); + + + diffa = abs(na2-na1);diffb =abs(nb2-nb1); + diffc = abs(nc2-nc1);diffd = abs(nd2-nd1); + maxs(1) = max(max(diffa));maxs(2) = max(max(diffb)); + maxs(3) = max(max(diffc));maxs(4) = max(max(diffd)); + + + maxs = maxs/6; + + d = min(1,signif(c*max(maxs))); + + ids(nn) = id; + idns(nn) = idn; + B(nn) = d; + + D(id) = D(id) + d; + D(idn) = D(idn) + d; + + nn = nn+1; + + end + + end + end + + end +end + +A = sparse(ids,idns,b); diff --git a/SD-VBS/common/toolbox/toolbox_basic/filter_hist/pair_dist_text4.m b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/pair_dist_text4.m new file mode 100755 index 0000000..83f3d49 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/pair_dist_text4.m @@ -0,0 +1,81 @@ +function [A] = pair_dist_text4(Iw,Cresult,cso) +% +% A = pair_dist_text3(Cum,cumhists); +% +% + +%s1 = Cum(2);s2 = Cum(1); + +figure(1);hold on;plot(cso(1),cso(2),'bo'); + +ws = [10,10]; + +lws = 3; +gap = 7; + +J1 = get_win(Iw,round(cso),ws); +Jbar1 = abs(get_win5(Cresult,round(cso),ws)); +hists1 = get_hist(J1,Jbar1); +cumhists1 = get_cumhist(hists1); +[na1,nb1,nc1,nd1] = ks_2d(cumhists1.text'); + +figure(4);colormap(gray); +imagesc(reshape(abs(Jbar1),size(Jbar1,1),size(Jbar1,2)*size(Jbar1,3))); +colorbar;axis('image');drawnow; + +figure(2); +subplot(2,5,1);imagesc(J1);%colormap(gray) +subplot(2,5,2);imagesc(hists1.text');title('hist_1');colorbar; +subplot(2,5,3);imagesc(cumhists1.text');title('cumhist_1');colorbar; +subplot(2,5,4);imagesc(nc1);title('nc_1');colorbar +subplot(2,5,5);imagesc(nb1);title('nb_1');colorbar +drawnow; + +k = sqrt(2)/2;M = prod(size(cumhists1.text)); +N = k*sqrt(M); +r1 = 0.001;r2 = 0.001; +con = N/(1+ (sqrt(1-0.5*(r1*r1+r2*r2)))*(0.25-0.75/N)); + +jid = 1; +for jj=cso(2)-lws*gap:gap:cso(2)+lws*gap, + kid = 1; + for kk=cso(1)-lws*gap:gap:cso(1)+lws*gap, + + figure(1);hold on; plot(kk,jj,'r*');drawnow; + + J2 = get_win(Iw,round([kk,jj]),ws); + Jbar2 = get_win5(Cresult,round([kk,jj]),ws); + + hists2 = get_hist(J2,Jbar2); + cumhists2 = get_cumhist(hists2); + [na2,nb2,nc2,nd2] = ks_2d(cumhists2.text'); + + figure(2); + subplot(2,5,6);imagesc(J2);%colormap(gray) + subplot(2,5,7);imagesc(hists2.text');title('hist_2');colorbar + subplot(2,5,8);imagesc(cumhists2.text');title('cumhist_2');colorbar + + diffa = abs(na2-na1);diffb =abs(nb2-nb1); + diffc = abs(nc2-nc1);diffd = abs(nd2-nd1); + + maxs(1) = max(max(diffa));maxs(2) = max(max(diffb)); + maxs(3) = max(max(diffc));maxs(4) = max(max(diffd)); + + maxs = maxs/6;for j=1:4, sig(j) = signif(con*maxs(j)); end + + subplot(2,5,9);imagesc(diffc);title('diff_{nc}');colorbar + subplot(2,5,10);imagesc(diffb);title('diff_{nb} ');colorbar + + disp(sprintf('max diff is %f\n',min(sig))); + + A(jid,kid) = min(1,min(sig)); + + %disp('press return to continue'); + pause(3); + + kid = kid+1; + end + jid = jid+1; +end + +figure(1);hold off; diff --git a/SD-VBS/common/toolbox/toolbox_basic/filter_hist/patch_cat.m b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/patch_cat.m new file mode 100755 index 0000000..0bf22c3 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/patch_cat.m @@ -0,0 +1,9 @@ +function T = patch_cat(dotfilter,text_des) + +T(:,:,2:7,:) = text_des; +clear text_des; + +for k=1:size(T,4), + T(:,:,1,k) = dotfilter(:,:,1,k); +end + diff --git a/SD-VBS/common/toolbox/toolbox_basic/filter_hist/pgmread.m b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/pgmread.m new file mode 100755 index 0000000..620408a --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/pgmread.m @@ -0,0 +1,15 @@ +function img = pgmread(filename,size) +% function img = pgmread(filename) +% this is my version of pgmread for the pgm file created by XV. +% +% this program also corrects for the shifts in the image from pm file. + +fid = fopen(filename,'r'); + +for j=1:4, + a = fgetl(fid); +end + +img = fscanf(fid,'%d',size); +img = img'; + diff --git a/SD-VBS/common/toolbox/toolbox_basic/filter_hist/poisson.m b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/poisson.m new file mode 100755 index 0000000..99d49b6 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/poisson.m @@ -0,0 +1,44 @@ +function [x] = Poisson(lambda); +%Poisson generates a random variable with a Poisson +% distribution +% Pr(x = n) = lambda^n exp(-lambda)/n +% +% [x] = Poisson(lambda); +% lambda: the parameter for the Poisson distribution +% (default is 1) +% x : the output number +% + +%% +%% (C) Thomas K. Leung +%% University of California at Berkeley +%% Apr 25, 1995. +%% + +%%% Notice that in this implementation, we are comparing log(Z) with +%%% T. In fact, we can compare T = exp(-lambda) with Z, which will +%%% save us from computing a large number of log's. However, when +%%% lambda is bigger than 709, exp(-lambda) = 0, which causes problem. + +if nargin == 0 + lambda = 1; +end + +if lambda < 0 + lambda = 1; +end + +P = 0; +N = 0; +T = -lambda; + +rand('seed',sum(100*clock)); + +while P >= T + Z = rand(1); + P = P + log(Z); + N = N + 1; +end + +x = N; + diff --git a/SD-VBS/common/toolbox/toolbox_basic/filter_hist/poissonfield.m b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/poissonfield.m new file mode 100755 index 0000000..8051867 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/poissonfield.m @@ -0,0 +1,53 @@ +function [x,y,success] = PoissonField(int,sx,sy,ir); +%BF_HardCore Generates a hard core Poisson field +% [x,y] = Poisson_HC(int,ir,sx,sy); +% int: intensity of the field. (default is 1) +% ir : inhibition radius (default is 1) +% sx : size in x (default 100) +% sy : size in y (default 100) +% x : x coordinates +% y : y coordinates +% + +%% +%% (C) Thomas K. Leung +%% University of California at Berkeley +%% April 26, 1995. +%% leungt@cajal.cs.berkeley.edu +%% + +%% +%% Generate each point in sequence and reject it if it's too close to +%% previous ones. +%% + +if nargin <= 0 + int = 1; + sx = 100; + sy = 100; + ir = 0; +elseif nargin <= 1 + sx = 100; + sy = 100; + ir = 0; +elseif nargin <= 2 + sy = 100; + ir = 0; +elseif nargin <= 3 + ir = 0; +end + +%% +%% Notice that the average number of a poisson process is the +%% parameter lambda. This is consistent with our definition of the +%% intensity here. Intensity is the mean number of points inside each +%% unit area. Therefore, in a window of sx by sy, we should get +%% int*sx*sy number of points on average which is the mean number of +%% arrivals in a Poisson Process +%% + +[n] = poisson(int * sx * sy); + +[x,y,success] = binomialfield(n,sx,sy,ir); + + diff --git a/SD-VBS/common/toolbox/toolbox_basic/filter_hist/proj_back.m b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/proj_back.m new file mode 100755 index 0000000..069fe61 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/proj_back.m @@ -0,0 +1,24 @@ +function mask = proj_back(I,hw,mask_s) +% +% mask = proj_back(I,hw,mask_s) +% +% + + +[nr,nc] = size(I2); + +hw = 3; +st_sz = 2*hw + 1; + +nr_chank = floor(nr/st_sz); +nc_chank = floor(nc/st_sz); + +[x,y] = meshgrid(1:nc,1:nr); + +ct_chank_x = round((x-hw-1)/st_sz) + 1; +ct_chank_y = round((y-hw-1)/st_sz) + 1; + +idx = (ct_chank_x - 1)*nr_chank + ct_chank_y; + +mask = full(sparse(y,x,mask_s(idx(:)))); + diff --git a/SD-VBS/common/toolbox/toolbox_basic/filter_hist/proj_back_id.m b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/proj_back_id.m new file mode 100755 index 0000000..9db322e --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/proj_back_id.m @@ -0,0 +1,19 @@ +function [vbig,bnr,bnc] = proj_back_id(v,gcs,gce,grs,gre) +% +% vbig = proj_back_id(v,gcs,gce,grs,gre) +% + +nr = max(gre)+1; +nc = max(gce)+1; + +sw = 3; +gap = 2*sw+1; + +bnc = nc*gap; +bnr = nr*gap; + +[x,y] = meshgrid(1:bnc,1:bnr); + +idx = grs(y(:))+1+gcs(x(:))*nr; + +vbig = full(sparse(y(:),x(:),v(idx))); diff --git a/SD-VBS/common/toolbox/toolbox_basic/filter_hist/quant.m b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/quant.m new file mode 100755 index 0000000..c2dfae6 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/quant.m @@ -0,0 +1,20 @@ +function [x,map] = quant(d1,d2,d3,nbin,ws) + +if (~exist('ws')), + ws = [1,1,1]; +end + +d1 = d1-min(d1); +d2 = d2-min(d2); +d3 = d3-min(d3); + +d1 = d1/max(d1); +d2 = d2/max(d2); +d3 = d3/max(d3); + +d1 = d1*ws(1); +d2 = d2*ws(2); +d3 = d3*ws(3); + + +[x,map] = vmquant(d1,d2,d3,nbin); diff --git a/SD-VBS/common/toolbox/toolbox_basic/filter_hist/readpdm.m b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/readpdm.m new file mode 100755 index 0000000..9a1068e --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/readpdm.m @@ -0,0 +1,8 @@ +function I = readpfm(filename) + +fid = fopen(filename,'r'); + +A = fscanf(fid,'%d',2); +I = fscanf(fid,'%d',[A(1),A(2)]); + +fclose(fid); diff --git a/SD-VBS/common/toolbox/toolbox_basic/filter_hist/readpfm.m b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/readpfm.m new file mode 100755 index 0000000..48ecd78 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/readpfm.m @@ -0,0 +1,10 @@ +function I = readpfm(filename) + +fid = fopen(filename,'r'); + +A = fscanf(fid,'%d',2); +I = fscanf(fid,'%f',[A(1),A(2)]); + +%I = fscanf(fid,'%f',A(2)*A(1));I = reshape(I,A(1),A(2)); + +fclose(fid); diff --git a/SD-VBS/common/toolbox/toolbox_basic/filter_hist/readpfm_id.m b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/readpfm_id.m new file mode 100755 index 0000000..5f5c4f7 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/readpfm_id.m @@ -0,0 +1,21 @@ +function Is = readpfm(filename,ids,nodes) + +fid = fopen(filename,'r'); + +A = fscanf(fid,'%d',2); + +Is = zeros(length(ids),nodes); + +ix = 1; +for j=1:max(ids), + I = fscanf(fid,'%f',nodes); + if (find(ids==j)), + Is(ix,:) = I(:)'; + ix = ix+1; + fprintf('.'); + end +end + +%I = fscanf(fid,'%f',A(2)*A(1));I = reshape(I,A(1),A(2)); + +fclose(fid); diff --git a/SD-VBS/common/toolbox/toolbox_basic/filter_hist/readpfm_idf.m b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/readpfm_idf.m new file mode 100755 index 0000000..d7916e7 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/readpfm_idf.m @@ -0,0 +1,29 @@ +function Is = readpfm(filename,ids,nodes) + +fid = fopen(filename,'r'); + +A = fscanf(fid,'%d',2); + +Is = zeros(length(ids),nodes); + +idt = sort(ids); + +idh = 1; + +ix = 1; +for j=1:length(ids), + + gap = idt(j) - idh; + fprintf('%d',gap); + + I = fscanf(fid,'%f',nodes*gap); + I = fscanf(fid,'%f',nodes); + + Is(find(ids==idt(j)),:) = I(:)'; + fprintf('.'); + + idh = idt(j)+1; +end + + +fclose(fid); diff --git a/SD-VBS/common/toolbox/toolbox_basic/filter_hist/readpgm.m b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/readpgm.m new file mode 100755 index 0000000..a5fd7f2 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/readpgm.m @@ -0,0 +1,26 @@ +function img = pgmread(filename) +% function img = pgmread(filename) +% this is my version of pgmread for the pgm file created by XV. +% +% this program also corrects for the shifts in the image from pm file. + + +fid = fopen(filename,'r'); +fscanf(fid, 'P5\n'); +cmt = '#'; +while findstr(cmt, '#'), + cmt = fgets(fid); + if length(findstr(cmt, '#')) ~= 1, + YX = sscanf(cmt, '%d %d'); + y = YX(1); x = YX(2); + end +end + +fgets(fid); + +%img = fscanf(fid,'%d',size); +%img = img'; + +img = fread(fid,[y,x],'uint8'); +img = img'; +fclose(fid); diff --git a/SD-VBS/common/toolbox/toolbox_basic/filter_hist/readpnm.m b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/readpnm.m new file mode 100755 index 0000000..ab78c2c --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/readpnm.m @@ -0,0 +1,21 @@ +function I = readpnm(name) + + fid = fopen(name, 'r'); + fscanf(fid, 'P5\n'); + cmt = '#'; + while findstr(cmt, '#') == 1 + cmt = fgets(fid); + if findstr(cmt, '#') ~= 1 + YX = sscanf(cmt, '%d %d %d'); + y = YX(1); x = YX(2); nb = YX(3); + end + end + fgets(fid); + packed = fscanf(fid,'%f',[nb*y*x]); + + for j = 1:nb, + I(:,:,j) = reshape(packed(j:nb:nb*y*x),y,x)'; + end + + fclose(fid); + diff --git a/SD-VBS/common/toolbox/toolbox_basic/filter_hist/readppm.m b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/readppm.m new file mode 100755 index 0000000..300f597 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/readppm.m @@ -0,0 +1,19 @@ +function [r, g, b] = readppm(name) + + fid = fopen(name, 'r'); + fscanf(fid, 'P6\n'); + cmt = '#'; + while findstr(cmt, '#') == 1 + cmt = fgets(fid); + if findstr(cmt, '#') ~= 1 + YX = sscanf(cmt, '%d %d'); + y = YX(1); x = YX(2); + end + end + fgets(fid); + packed = fread(fid,[3*y,x],'uint8')'; + r = packed(:,1:3:3*y); + g = packed(:,2:3:3*y); + b = packed(:,3:3:3*y); + fclose(fid); + diff --git a/SD-VBS/common/toolbox/toolbox_basic/filter_hist/record.m b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/record.m new file mode 100755 index 0000000..9626038 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/record.m @@ -0,0 +1,6 @@ +load patch1; +doog2 = mkdoog2(2,10,0,80); +dog2 = rotate_J(90,doog2); + +H = mkf_test(dog2,size(patch1),-1,0.00001,2,-1); +o = BfilterS(patch1,H,size(dog));figure(4);colormap(gray);imagesc(o.*(o>0)); \ No newline at end of file diff --git a/SD-VBS/common/toolbox/toolbox_basic/filter_hist/recursive_cut_tc.m b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/recursive_cut_tc.m new file mode 100755 index 0000000..a8c9362 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/recursive_cut_tc.m @@ -0,0 +1,140 @@ +%function [groups,ids] = recursive_cut(ncutv,fn_base) +% +% +% function [groups,ids] = recursive_cut(ncutv,threshold,spthresh) +% +% + +ncutv= ncutv_o(:,1:4); + +fn_base = fn; +%fn_base = '130040'; + +nvv = size(ncutv_o,2); +nbin = 24; + +ids = []; +groups = []; +labels = []; + +load cmaps +cmap = cmapg; + +j = 1; +done = 0; +np = size(ncutv,1); +nv = size(ncutv,2); + +%%%%%% find the cut for the first ncut vector +ev_id = 2; +para = [nvv ev_id nr nc 100]; +Gmask = ones(nr,nc); +%threshold = find_cutpoint(ncutv(:,ev_id),cmapg,nbin);threshold = threshold(1:end-1); +threshold = linspace(min(ncutv(:,ev_id)),max(ncutv(:,ev_id)),nbin); +[cut_threshold,max_asso] = find_bst_cut(fn_base,para,threshold,Gmask); +disp(max_asso); + +id1 = find(ncutv(:,ev_id)<=cut_threshold); +id2 = find(ncutv(:,ev_id)>cut_threshold); + +groups = [groups,id1(:)']; +ids = [ids,length(id1)]; + +groups = [groups,id2(:)']; +ids = [ids,length(groups)]; + + +for j=3:nv, + fprintf('j = %d\n',j); + % expand the current level, + new_groups = []; + new_ids = []; + + + figure(4);ims(ncutv(:,j),nr,nc);title(num2str(j)); + + figure(1);clf + disp_groups(groups,ids,nr,nc); + drawnow; + + %figure(3); + % for each leaves, + mx = max(ncutv(:,j))-min(ncutv(:,j)); + %mx = std(ncutv(:,j)); + + base_id =1; + for k=1:length(ids), + old_groups = groups(base_id:ids(k)); + + v = ncutv(old_groups,j); + change_v = max(v)-min(v); + %change_v = std(v); + n1 = sum(v>(min(v)+0.85*change_v));%n1 = n1/length(old_groups); + n2 = sum(v<=(min(v)+0.15*change_v));%n2 = n2/length(old_groups); + disp(sprintf('n1 = %f, n2 = %f',n1,n2)); + + figure(2); + Gmask = zeros(np,1); + Gmask(old_groups) = Gmask(old_groups)+1; + drawnow; + ims(ncutv(:,j).*Gmask,nr,nc); + + disp(sprintf('!!!!!!!!!!!!!RATIO= %f',change_v/mx)) + + %pause; + + if (((change_v/mx)>0.5) & (n1>10) &(n2>10)), + + ev_id = j; + + %threshold = find_cutpoint(ncutv(old_groups,ev_id),cmapg,nbin);threshold = threshold(1:end-1); + threshold = linspace(min(ncutv(:,ev_id)),max(ncutv(:,ev_id)),nbin); + para = [nvv ev_id nr nc 100]; + [cut_threshold,max_asso] = find_bst_cut(fn_base,para,threshold,Gmask); + + disp(max_asso); + + if (max_asso>1.2), + id1 = find(ncutv(old_groups,ev_id)<=cut_threshold); + id2 = find(ncutv(old_groups,ev_id)>cut_threshold); + + figure(5); + subplot(1,2,1);maskt= zeros(np,1);maskt(old_groups(id1))=1+maskt(old_groups(id1));ims(maskt,nr,nc); + subplot(1,2,2);maskt= zeros(np,1);maskt(old_groups(id2))=1+maskt(old_groups(id2));ims(maskt,nr,nc); + + new_groups = [new_groups,old_groups(id1)]; + new_ids = [new_ids,length(new_groups)]; + + + new_groups = [new_groups,old_groups(id2)]; + new_ids = [new_ids,length(new_groups)]; + else + fprintf(' keep '); + new_groups = [new_groups,old_groups]; + new_ids = [new_ids,length(new_groups)]; + end + + else + fprintf(' keep '); + new_groups = [new_groups,old_groups]; + new_ids = [new_ids,length(new_groups)]; + end + fprintf('\n'); + base_id = ids(k) + 1; + end + + + + groups = new_groups; + ids = new_ids; + + figure(1);disp_groups(groups,ids,nr,nc); + + fprintf('press return\n'); + pause; + j= j+1; +end + +fprintf('total group = %d \n',length(ids)); + + diff --git a/SD-VBS/common/toolbox/toolbox_basic/filter_hist/reduce_all.m b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/reduce_all.m new file mode 100755 index 0000000..d7d31f8 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/reduce_all.m @@ -0,0 +1,8 @@ +function b = reduce_all(a) + +numband = size(a,3); + +for j=1:numband, + + b(:,:,j) = reduce(a(:,:,j)); +end diff --git a/SD-VBS/common/toolbox/toolbox_basic/filter_hist/rotate_J.m b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/rotate_J.m new file mode 100755 index 0000000..12f29b6 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/rotate_J.m @@ -0,0 +1,30 @@ +function J = compute_J(angle,I) +%% function J = compute_J(angle,I) +% + +[size_y,size_x] = size(I); + +[center_x,center_y] = find_center(size_x,size_y); + +a = angle * pi/180; +A = [cos(a),-sin(a);sin(a),cos(a)]; + +[XX,YY] = meshgrid(1:size_x,1:size_y); + +x = reshape(XX,size_x*size_y,1); +y = reshape(YY,size_x*size_y,1); +index(:,1) = x-center_x; +index(:,2) = y-center_y; + +position_new = A*index'; +position_new(1,:) = position_new(1,:)+center_x; +position_new(2,:) = position_new(2,:)+center_y; + +position_new_x = reshape(position_new(1,:),size_y,size_x); +position_new_y = reshape(position_new(2,:),size_y,size_x); + +J = m_interp4(I,position_new_x,position_new_y); + + + + diff --git a/SD-VBS/common/toolbox/toolbox_basic/filter_hist/session.m b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/session.m new file mode 100755 index 0000000..70fabbf --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/session.m @@ -0,0 +1,4 @@ +t = rj(1:50,19:50); tt = interp4(t,1); +sgn = mksgn2(182,2,[91,9]); +H = mkf_test(sgn,size(tt),1,0.01,2,300); +o = BfilterS(tt,H,size(sgn));figure(1);imagesc(o.*(o>0));axis('equal'); diff --git a/SD-VBS/common/toolbox/toolbox_basic/filter_hist/show_cumhist.m b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/show_cumhist.m new file mode 100755 index 0000000..fe82e64 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/show_cumhist.m @@ -0,0 +1,28 @@ +function show_hist(cumhists,bins,fig_id,hold_flag,ct) +%% +% show_hist(cumhists,bins,fig_id,ct) +% +% + + if (~exist('ct')), + ct = 'b-o'; + end + + figure(fig_id); + + subplot(3,3,1);plot(bins.inten,cumhists.inten,ct); + + if (hold_flag == 1), hold on;else hold off; end + + for j=1:size(cumhists.text,2), + subplot(3,3,1+j); + plot(bins.text,cumhists.text(:,j),ct); + if (hold_flag == 1), hold on;else hold off; end + end + + subplot(3,3,8); + plot(bins.mag,cumhists.mag,ct); + if (hold_flag == 1), hold on;else hold off; end + + + diff --git a/SD-VBS/common/toolbox/toolbox_basic/filter_hist/show_hist.m b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/show_hist.m new file mode 100755 index 0000000..efaf899 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/show_hist.m @@ -0,0 +1,23 @@ +function show_hist(hists,bins,fig_id) +%% +% show_hist(hists,bins,fig_id) +% +% + + figure(fig_id); + + subplot(3,3,1);bar(bins.inten,hists.inten); + + %maxval = max(max(max(abs(Jbar)))); + + for j=1:size(hists.text,2), + subplot(3,3,1+j);% hist(reshape(abs(Jbar(:,:,j)),prod(w),1),[1:10:maxval+1]); + bar(bins.text,hists.text(:,j)); + end + + subplot(3,3,8);%hist(reshape(sum(abs(Jbar),3),prod(w),1),[1:10:161]); + bar(bins.mag,hists.mag); + + + + diff --git a/SD-VBS/common/toolbox/toolbox_basic/filter_hist/showsmm.m b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/showsmm.m new file mode 100755 index 0000000..1833062 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/showsmm.m @@ -0,0 +1,45 @@ +function [T,A,M2,TAM]=showsmm(L1,L2,phi,maxM); +% [T,A,M]=showsmm(L1,L2,phi,maxM); + +if (~exist('maxM')), +% needs to know upper bound on M for given window function in smm +maxM=0.18; % temporary +end + + +A=1-L2./(L1+eps); +T=2*(phi+pi/2)/(2*pi); +M=L1+L2; +M2=min(M/maxM,1); % keep it from exceeding 1 +%M2 = sigmoid(M,maxM,30); + +matlab5on = 1; + +if matlab5on == 1, + TAM=hsv2rgb(T,A,M2); + + figure(3); + image(TAM); + axis('tightequal'); +else + H = [reshape(T,prod(size(T)),1),... + reshape(A,prod(size(A)),1),... + reshape(M2,prod(size(M2)),1)]; + M = hsv2rgb(H); + [Ic,map] =vmquant(M(:,1),M(:,2),M(:,3),256); + + image(reshape(Ic,size(T,1),size(T,2)));colormap(map); +end + +if 0 + plot3(A(:).*M(:).*cos(2*pi*T(:)),A(:).*M(:).*sin(2*pi*T(:)),M(:),'.','markersize',15) + axis([-1 1 -1 1 0 1]) + [x,y,z] = cylinder(ones(1,5)); + x=x.*z; + y=y.*z; + hold on + h=mesh(x,y,z); + set(h,'edgecolor',[.2 .2 .2]); + hidden off + hold off +end \ No newline at end of file diff --git a/SD-VBS/common/toolbox/toolbox_basic/filter_hist/showsmm_v5.m b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/showsmm_v5.m new file mode 100755 index 0000000..937303d --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/showsmm_v5.m @@ -0,0 +1,34 @@ +function [T,A,M2,TAM]=showsmm(L1,L2,phi,maxM); +% [T,A,M]=showsmm(L1,L2,phi,maxM); + +if (~exist('maxM')), +% needs to know upper bound on M for given window function in smm +maxM=0.18; % temporary +end + + +A=1-L2./(L1+eps); +T=2*(phi+pi/2)/(2*pi); +M=L1+L2; +M2=min(M/maxM,1); % keep it from exceeding 1 +%M2 = sigmoid(M,maxM,30); + + TAM=hsv2rgb(T,A,M2); + + figure(3); + image(TAM); + axis('tightequal'); + + +if 0 + plot3(A(:).*M(:).*cos(2*pi*T(:)),A(:).*M(:).*sin(2*pi*T(:)),M(:),'.','markersize',15) + axis([-1 1 -1 1 0 1]) + [x,y,z] = cylinder(ones(1,5)); + x=x.*z; + y=y.*z; + hold on + h=mesh(x,y,z); + set(h,'edgecolor',[.2 .2 .2]); + hidden off + hold off +end \ No newline at end of file diff --git a/SD-VBS/common/toolbox/toolbox_basic/filter_hist/sigmoid.m b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/sigmoid.m new file mode 100755 index 0000000..996f7fe --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/sigmoid.m @@ -0,0 +1,10 @@ +function a = sigmoid(x,offset,sig) +% +% a = sigmoid(x,offset,sig) +% +% a = ones(size(x))./(1+exp(-(x-offset)/sig)); +% + + +a = ones(size(x))./(1+exp(-(x-offset)/sig)); + diff --git a/SD-VBS/common/toolbox/toolbox_basic/filter_hist/signif.m b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/signif.m new file mode 100755 index 0000000..f49eefc --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/signif.m @@ -0,0 +1,22 @@ +function a = signif(b) + +js = [1:101]; + + +if 0, +d = (-ones(size(js))).^(js-1); +d1 = exp(-2*(js.*js)*b*b); + +a = 2*sum(d.*d1); + +end + +d1 = exp(-2*(js.*js)*b*b); +d2 = 4*(js.*js)*b*b - 1; + +a = 2*sum(d1.*d2); + +if (b<0.03),a = 1;end + + + diff --git a/SD-VBS/common/toolbox/toolbox_basic/filter_hist/signif_N.m b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/signif_N.m new file mode 100755 index 0000000..82dc914 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/signif_N.m @@ -0,0 +1,10 @@ +function a = signif_N(b,N) +% +% +% + +Ne = sqrt(N*0.5); + +cof = Ne + 0.155 + 0.24/Ne; + +a= signif(cof*b); diff --git a/SD-VBS/common/toolbox/toolbox_basic/filter_hist/smooth.m b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/smooth.m new file mode 100755 index 0000000..919b53a --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/smooth.m @@ -0,0 +1,20 @@ +% smooth an image +% coordinates (r, c) follow matrix convention; +% the gaussian is truncated at x = +- tail, and there are samples samples +% inbetween, where samples = hsamples * 2 + 1 + +function g = smooth(image, hsamples) + +tail=4; +samples = hsamples * 2 + 1; + +x = linspace(-tail, tail, samples); +gauss = exp(-x.^2); +n = gauss * ones(samples,1); +gauss = gauss/n; + + +g = conv2(conv2(image, gauss), gauss'); + +g = conv_trim(g, hsamples, hsamples); + diff --git a/SD-VBS/common/toolbox/toolbox_basic/filter_hist/startup.m b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/startup.m new file mode 100755 index 0000000..8d38803 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/startup.m @@ -0,0 +1,9 @@ +%path(path,'/usr/sww/matlab-4.2c/toolbox/images'); +home_dir = '/home/barad-dur/vision/malik/jshi/'; +path(path,[home_dir,'matlab/toolbox/io']) +path(path,[home_dir,'matlab/pyramid']); +path(path,[home_dir,'matlab/toolbox/filter']) +path(path,[home_dir,'matlab/toolbox/disp']) +path(path,[home_dir,'matlab/vision/vision94/tracking/']) +path(path,[home_dir,'proj/grouping/laso']); +path(path,[home_dir,'proj/grouping/eig']); diff --git a/SD-VBS/common/toolbox/toolbox_basic/filter_hist/swarp.m b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/swarp.m new file mode 100755 index 0000000..60a4530 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/swarp.m @@ -0,0 +1,9 @@ +function J = swarp(I) + +[nr,nc] = size(I); + +center_x = round(0.5*nc); +center_y = round(0.5*nr); + +J = [I(center_y:nr,center_x:nc),I(center_y:nr,1:center_x-1);... + I(1:center_y-1,center_x:nc),I(1:center_y-1,1:center_x-1)]; \ No newline at end of file diff --git a/SD-VBS/common/toolbox/toolbox_basic/filter_hist/swarpback.m b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/swarpback.m new file mode 100755 index 0000000..513bc25 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/swarpback.m @@ -0,0 +1,12 @@ +function J = swarpback(I); + +[nr,nc] = size(I); + +center_x = round(0.5*nc); +center_y = round(0.5*nr); + +cx= center_x -1; +cy= center_y -1; + +J = [I(nr-cy+1:nr,nc-cx+1:nc),I(nr-cy+1:nr,1:(nc-center_x+1));... + I(1:(nr-center_y+1),nc-cx+1:nc),I(1:(nr-center_y+1),1:(nc-center_x+1))]; \ No newline at end of file diff --git a/SD-VBS/common/toolbox/toolbox_basic/filter_hist/test.m b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/test.m new file mode 100755 index 0000000..12470eb --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/test.m @@ -0,0 +1,110 @@ + +fn = '130065'; nr = 30;nc = 49; +%nr = 49;nc = 30; +%nc = 68;nr = 43; +%nr =49;nc = 30; + +basedir = 'plaatje_data/newdata/'; +if 1, +fname = sprintf('%s%s_eigvec.pfm',basedir,fn); +eigv = readpfm(fname); +fname = sprintf('%s%s_eigval.pfm',basedir,fn); +eigval = readpfm(fname); + +fname = sprintf('%s%s_ncutvec.pfm',basedir,fn); +ncutv = readpfm(fname); +fname = sprintf('%s%s_ncutval.pfm',basedir,fn); +ncutval = readpfm(fname); +else +fname = sprintf('%sncutvec_%s.pfm',basedir,fn); +ncutv = readpfm(fname); +fname = sprintf('%sncutval_%s.pfm',basedir,fn); +ncutval = readpfm(fname); +end + + +fname = sprintf('images/%s.pgm',fn); +I = readpgm(fname); +cutsz = 20; I = cutoff(I,cutsz); +figure(3);im(I);colormap(gray); + +figure(6); +for j=1:min(8,size(ncutv,2)-1), + subplot(3,3,j); + im(reshape(ncutv(:,j+1),nr,nc));colorbar + title(num2str(ncutval(j+1,1))); +end +%cm = sprintf('print -dps ncut_%s',fn);disp(cm);eval(cm); +subplot(3,3,9);im(I);axis('off'); + +ev = eigval(:,1); +figure(5);hold off;clf;subplot(1,2,1); +%semilogy((ev(1:end-1) - ev(2:end))./ev(1:end-1),'x-');grid on; +plot((ev(1:end-1) - ev(2:end))./ev(1:end-1),'x-');grid on; +%semilogy(0.01*ones(size(ev(2:end-1))),'r-');semilogy(0.005*ones(size(ev(2:end-1))),'r-');semilogy(0.0025*ones(size(ev(2:end-1))),'r-');grid on;hold off; +subplot(1,2,2); +%semilogy(ev(1:end-1)-ev(2:end),'p-');grid on; +semilogy((ev(1:end-1) - ev(2:end))/ev(1),'x-');grid on; + + +ncutv_o = ncutv; + +recursive_cut_tc; + +%[groups,ids] = recursive_cut(ncutv(:,1:4),fn); + +masks = make_masks(groups,ids,nr,nc); + +cm = sprintf('save masks_%s masks ncutv_o groups ids nr nc',fn); +disp(cm); + +eval(cm); + + +%%%%%%%%%%%%%%%%%% +fn = '130040'; +cm = sprintf('load masks_%s',fn); +disp(cm); +eval(cm); + +fn = '130040'; +fname= sprintf('images/%s.pgm',fn); +I = readpgm(fname);cutsz = 20; I = cutoff(I,cutsz); +figure(3);im(I);colormap(gray); +hw = 2; %nr = 43;nc=68; +gap = 2*hw+1; +%nr = 30;nc=49; +Is = I(1:nr*gap,1:nc*gap); +figure(3);im(Is);axis('off'); + +%cm = sprintf('print -deps I_%s',fn);disp(cm);eval(cm); + + + +%masks = make_masks(groups,ids,nr,nc); +figure(2);disp_groups(groups,ids,nr,nc); + +figure(1); +Imasks = disp_Imask(Is,nr,nc,hw,masks); + +for j=1:length(ids), + figure(4);colormap(gray);clf + im(Imasks(:,:,j));axis('off'); + cm = sprintf('print -deps result_cut_%s_%d',fn,j); + disp(cm);eval(cm); + + %print -deps result_cut_134011_1 +end + + +if 0, + +%load st_134013 + +fn = '134013_t'; + +I_max = 250; +tex_max = 40; + +writeout_feature(I1,T1,fn,I_max,tex_max); +end diff --git a/SD-VBS/common/toolbox/toolbox_basic/filter_hist/test1.m b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/test1.m new file mode 100755 index 0000000..691b63e --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/test1.m @@ -0,0 +1,175 @@ + +fnameI = '130068'; + +cm = sprintf('load filter_%s.pgm.mat',fnameI); +disp(cm); +eval(cm); + +text_des = abs(text_des); + + + %%%% cutoff margins, +margin = 6+10; + +Iw = cutoff(I,margin); + +T1= reshape(text_des,size(text_des,1),size(text_des,2),size(text_des,3)*size(text_des,4)); +T1 = cutoff(T1,margin); + +%%%%% reduce resolution + + + +T1 = reduce_all(T1); +T1 = reduce_all(T1); + +im5(T1,5,6); + +cm = sprintf('writepnm5(''%s_f.pnm'',%s)',fnameI,'T1/70'); + +% disp(cm);eval(cm); + +nr = size(T1,1); +nc = size(T1,2); + +% D = mreadpfm('D_134011_f.pnm.pfm'); + +% figure(3);imagesc(reshape(D,nc,nr)');axis('image');colorbar + +if 0, +figure(7); +subplot(3,1,1);hist(reshape(I1,prod(size(I1)),1),binI); +subplot(3,1,2);hist(reshape(I2,prod(size(I2)),1),binI); +subplot(3,1,3);hist(reshape(I3,prod(size(I3)),1),binI); + + +If1 = filter_output(I1,sigs,szs); +If2 = filter_output(I2,sigs,szs); +If3 = filter_output(I3,sigs,szs); + +I1a = cutoff(I1,5); If1 = cutoff(If1,5); +I2a = cutoff(I2,5); If2 = cutoff(If2,5); +I3a = cutoff(I3,5); If3 = cutoff(If3,5); + + + +figure(4); +bint = [-0.15:0.02:0.15]; +id = 4; + +If = If1; +for j=1:5, + subplot(5,2,2*(j-1)+1); + hist(reshape(If(:,:,id,j)./s1,prod(size(If(:,:,id,j))),1),bint); +end + +If = If2; +for j=1:5, + subplot(5,2,2*j); + hist(reshape(If(:,:,id,j)./s2,prod(size(If(:,:,id,j))),1),bint); +end + + +%%% make 2d histogram bin +figure(5); +idmax = 5; +filt_id = 4; + +for id=1:idmax, + + subplot(idmax,3,(id-1)*3+1); + h2d1 = hist_I_f(I1a,If1(:,:,filt_id,id),binI,bintex); + imagesc(h2d1);axis('image') + subplot(idmax,3,(id-1)*3+2); + h2d2 = hist_I_f(I2a,If2(:,:,filt_id,id),binI,bintex); + imagesc(h2d2);axis('image') + + subplot(idmax,3,id*3); + imagesc(h2d2/sum(sum(h2d2)) + h2d1/sum(sum(h2d1)));axis('image') + colorbar +end + +%%%%%%%%%%%%%%%%%%%%% three types %%%%%%%% +figure(4); +idmax = 5; +filt_id = 2; + +width = 4; + +for id=1:idmax, + + subplot(idmax,width,(id-1)*width+1); + h2d1 = hist_I_f(I1a,If1(:,:,filt_id,id),binI,bintex); + h2d1 = h2d1/sum(sum(h2d1)); + imagesc(h2d1);axis('image'); + + subplot(idmax,width,(id-1)*width+2); + h2d2 = hist_I_f(I2a,If2(:,:,filt_id,id),binI,bintex); + h2d2 = h2d2/sum(sum(h2d2)); + imagesc(h2d2);axis('image') + + subplot(idmax,width,(id-1)*width+3); + h2d3 = hist_I_f(I3a,If3(:,:,filt_id,id),binI,bintex); + h2d3 = h2d3/sum(sum(h2d3)); + imagesc(h2d3);axis('image') + + subplot(idmax,width,id*width); + imagesc(h2d1+h2d2+h2d3);axis('image') + colorbar +end + + +%%%%%%%%%%%% smaller window %%%% +hw = round(4*sigs(1)); + +figure(5);%imagesc(I1a);axis('image'); +cs = round(ginput(1)); + +J = get_win(I1a,cs,[hw,hw]);figure(7);imagesc(J);axis('image'); + +Jf = get_win5(If1,cs,[hw,hw]); +scales = 1:5; nscales = length(scales); +filters = 1:7; nfilters = length(filters); + +figure(8); +for j=1:nscales, + for k=1:nfilters, + subplot(nscales,nfilters,(j-1)*nfilters+k); + h2d = hist_I_f(J,Jf(:,:,(j-1)*7+k));h2d = h2d/sum(sum(h2d)); + imagesc(h2d);axis('image');colorbar;axis('off'); + end +end + + +if 0, + + figure(3); + cs = ginput(1); + + ws = [15,15]; + J = get_win(I,cs,ws); + figure(6);imagesc(J);axis('image'); + + t1 = get_win5(text_des,cs,ws); + + t1p = abs(t1); + %t1p = abs(t1); + %t1p = t1.*(t1>0); + + figure(2);im5(t1p,5,6); + + t1p = reshape(t1p,size(t1p,1)*size(t1p,2),size(t1p,3))'; + + t1pm = mean(t1p')'; + t1ps = t1p- t1pm*ones(1,size(t1p,2)); + + B = t1ps*t1ps'; + [v,d] = eig(B);d = diag(d); + figure(4);plot(d,'x-'); + + figure(5); + subplot(2,2,1);vid = 30;plot(reshape(v(:,vid),6,5),'x-'); + +end + +end diff --git a/SD-VBS/common/toolbox/toolbox_basic/filter_hist/test2.m b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/test2.m new file mode 100755 index 0000000..c70446a --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/test2.m @@ -0,0 +1,220 @@ + +%fnameI = '130056'; +%fnameI = '134013'; +fnameI = '134007'; + +%%%% flags %%%%%%%%% +read_image = 1; + +margin = 10+6; +sigs = [1/sqrt(2),1,sqrt(2),2,2*sqrt(2)]; +r =3; +szs = round(3*r*sigs); + + + +%%% image read %%% +if read_image, + cm = sprintf('I = readpgm(''images/%s.pgm'');',fnameI); + disp(cm); + eval(cm); + + Iw = cutoff(I,margin); + figure(1);imagesc(Iw);axis('image'); +end + +%%%% image crop %%% +figure(1);J = imcrop; +figure(2);imagesc(J);axis('image');drawnow; + +Jf = filter_output(J,sigs,szs); +margin = 5; +Ja = cutoff(J,margin);Jfa = cutoff(Jf,margin); +figure(2);imagesc(Ja);axis('image'); + +figure(3); +imagesc(Jfa(:,:,1,3));axis('image');drawnow; + +Jfb = reshape(Jfa,size(Jfa,1),size(Jfa,2),size(Jfa,3)*size(Jfa,4)); +mag = sum(abs(Jfb),3); + +%%%%%% Joint hist. %%%%%%%%% + +filter_id = 1; +scale = 1; +h2d = hist_I_f(Ja,Jfa(:,:,filter_id,scale)); + +figure(4); +imagesc(h2d/sum(sum(h2d)));axis('image');colorbar;colormap(hot); + + +%%%%%%%%%% Jointe hist of cropped area %%%%% +%%% block 1 +fig_id = 1; +[J3,f3,rect] = crop_im_fil(Ja,Jfa,fig_id); + +filter_id = 1;scale = 1;H1 = hist_I_f(J1,f1(:,:,filter_id,scale)); + + +%%% block 2 +fig_id = 1; +[J2,f2,rect] = crop_im_fil(Ja,Jfa,fig_id); + +filter_id = 1;scale = 1;H2 = hist_I_f(J2,f2(:,:,filter_id,scale)); + + +%%%%% disp result %%%%% + +scales = [1:5]; +filter_ids = [1:7]; + +figure(6);disp_hist2d(J2,f2,scales,filter_ids); + +figure(4);disp_hist2d(J1,f1,scales,filter_ids); + +%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%% smaller window +hw = round(4*sigs(1)); + +figure(2);%imagesc(Ja);axis('image'); +cs = round(ginput(1)); + +J1 = get_win(Ja,cs,[hw,hw]);Jf1 = get_win5(Jfa,cs,[hw,hw]); +figure(4);imagesc(J1);axis('image');drawnow; +scales = [1:5];filter_ids = [1:7]; +figure(9);H2 = disp_hist2d(J1,Jf1,scales,filter_ids); + +figure(6); disp_diff(H2,H2o); + + +%%%%%% difference in the neighbourhood %% +hw = round(4*sigs(1)); +hnb = 3; + +B = compute_diff(Ja,Jfa,hw,hnb); + + +%%%%%%%%%% + +if 0, + +figure(4); +bint = [-0.15:0.02:0.15]; +id = 4; + +If = If1; +for j=1:5, + subplot(5,2,2*(j-1)+1); + hist(reshape(If(:,:,id,j)./s1,prod(size(If(:,:,id,j))),1),bint); +end + +If = If2; +for j=1:5, + subplot(5,2,2*j); + hist(reshape(If(:,:,id,j)./s2,prod(size(If(:,:,id,j))),1),bint); +end + + +%%% make 2d histogram bin +figure(5); +idmax = 5; +filt_id = 4; + +for id=1:idmax, + + subplot(idmax,3,(id-1)*3+1); + h2d1 = hist_I_f(I1a,If1(:,:,filt_id,id),binI,bintex); + imagesc(h2d1);axis('image') + subplot(idmax,3,(id-1)*3+2); + h2d2 = hist_I_f(I2a,If2(:,:,filt_id,id),binI,bintex); + imagesc(h2d2);axis('image') + + subplot(idmax,3,id*3); + imagesc(h2d2/sum(sum(h2d2)) + h2d1/sum(sum(h2d1)));axis('image') + colorbar +end + +%%%%%%%%%%%%%%%%%%%%% three types %%%%%%%% +figure(4); +idmax = 5; +filt_id = 2; + +width = 4; + +for id=1:idmax, + + subplot(idmax,width,(id-1)*width+1); + h2d1 = hist_I_f(I1a,If1(:,:,filt_id,id),binI,bintex); + h2d1 = h2d1/sum(sum(h2d1)); + imagesc(h2d1);axis('image'); + + subplot(idmax,width,(id-1)*width+2); + h2d2 = hist_I_f(I2a,If2(:,:,filt_id,id),binI,bintex); + h2d2 = h2d2/sum(sum(h2d2)); + imagesc(h2d2);axis('image') + + subplot(idmax,width,(id-1)*width+3); + h2d3 = hist_I_f(I3a,If3(:,:,filt_id,id),binI,bintex); + h2d3 = h2d3/sum(sum(h2d3)); + imagesc(h2d3);axis('image') + + subplot(idmax,width,id*width); + imagesc(h2d1+h2d2+h2d3);axis('image') + colorbar +end + + +%%%%%%%%%%%% smaller window %%%% +hw = round(4*sigs(1)); + +figure(5);%imagesc(I1a);axis('image'); +cs = round(ginput(1)); + +J = get_win(I1a,cs,[hw,hw]);figure(7);imagesc(J);axis('image'); + +Jf = get_win5(If1,cs,[hw,hw]); +scales = 1:5; nscales = length(scales); +filters = 1:7; nfilters = length(filters); + +figure(8); +for j=1:nscales, + for k=1:nfilters, + subplot(nscales,nfilters,(j-1)*nfilters+k); + h2d = hist_I_f(J,Jf(:,:,(j-1)*7+k));h2d = h2d/sum(sum(h2d)); + imagesc(h2d);axis('image');colorbar;axis('off'); + end +end + + +if 0, + + figure(3); + cs = ginput(1); + + ws = [15,15]; + J = get_win(I,cs,ws); + figure(6);imagesc(J);axis('image'); + + t1 = get_win5(text_des,cs,ws); + + t1p = abs(t1); + %t1p = abs(t1); + %t1p = t1.*(t1>0); + + figure(2);im5(t1p,5,6); + + t1p = reshape(t1p,size(t1p,1)*size(t1p,2),size(t1p,3))'; + + t1pm = mean(t1p')'; + t1ps = t1p- t1pm*ones(1,size(t1p,2)); + + B = t1ps*t1ps'; + [v,d] = eig(B);d = diag(d); + figure(4);plot(d,'x-'); + + figure(5); + subplot(2,2,1);vid = 30;plot(reshape(v(:,vid),6,5),'x-'); + +end + +end diff --git a/SD-VBS/common/toolbox/toolbox_basic/filter_hist/test3.m b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/test3.m new file mode 100755 index 0000000..040ed3d --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/test3.m @@ -0,0 +1,4 @@ +fn = 'lightsmall.ppm'; +nr = Ipara(1);nc = Ipara(2); + +k = 1;imagesc(reshape(v(:,k).*D,nc,nr)');colorbar \ No newline at end of file diff --git a/SD-VBS/common/toolbox/toolbox_basic/filter_hist/test_best_cut.m b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/test_best_cut.m new file mode 100755 index 0000000..e04c6ff --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/test_best_cut.m @@ -0,0 +1,12 @@ + +fn_base = '134035'; +ev_id = 4; +para = [12 ev_id nr nc 100]; +Gmask = ones(nr,nc); +threshold = find_cutpoint(ncutv(:,ev_id),cmapg,12); +threshold = threshold(1:end-1); + +cut_threshold = find_bst_cut(fn_base,para,threshold,Gmask); + +figure(8);ims(ncutv(:,ev_id)0.2*max(max(abs(tmp))))); + + tmp = vs(idx,1:3)*vs(:,1:3)';tmp = reshape(tmp,size(Is,1),size(Is,2)); + subplot(3,2,3); + im(abs(tmp));colorbar; + subplot(3,2,4); im((Is+0.5).*(abs(tmp)>0.2*max(max(abs(tmp))))); + + tmp = vs(idx,1:5)*vs(:,1:5)'; + tmp = reshape(tmp,size(Is,1),size(Is,2)); + subplot(3,2,5); + im(abs(tmp));colorbar + subplot(3,2,6); im((Is+0.5).*(abs(tmp)>0.2*max(max(abs(tmp))))); + +end + + +%%%%%%%%%% +test_tmp = 0; +if test_tmp, +x = -10:0.02:20; +sig = 4; +d = exp(-(x.^2)/sig); +figure(2);plot(x,d); + +ers = []; +for j=0:0.5:10, + d1 = exp(-(x-j).^2/sig); + hold on + plot(x,d1,'r'); + ers = [ers,sum((d1-d).^2)]; +end +hold off; + +figure(1);plot(ers(end)-ers); + + + + + + +end + +%%%%%%%%%%%%%%%%%%% + + +fvs = colize(ts,Is); + +nf = 24;np = 0.5*7442; +hb.sigs = 0.02*ones(1,nf); +hb.bmins= -0.6*ones(1,nf); +hb.bmaxs= 0.6*ones(1,nf); +hb.nbins= 20*ones(1,nf); + +%fh = colize_hist(fvs(1:nf,1:10:end),hb); + +fh2 = hist_inner(fvs(1:nf,1:np),hb); + +[u,d] = eigs(fh2,60); d = diag(d); + +%%%%%%%%%%%% +figure(12); + ct = round(ginput(1)); + idx = (ct(:,1)-1)*size(Is,1) + ct(:,2); + +dist = dist_pair(idx,fvs(1:nf,:),hb); +figure(4); +im(reshape(dist,size(Is,1),size(Is,2)));colorbar + + +%%%%%%%%% +figure(12); + ct = round(ginput(1)); + idx = (ct(:,1)-1)*size(Is,1) + ct(:,2); + +a = colize_hist(fvs(1:nf,idx'),hb); + +figure(5); +cl = 'brgm'; +for j=1:length(idx); + plot(a(:,j),cl(j)); + hold on; +end +hold off + +%%%%%%%%%%% + +%% use chanked feature vectors + +chank_size = 1000; +fname = 'st'; +histbin_fv_chank(fvs(1:nf,:),hb,chank_size,fname); + + +covfh2 = hist_in_chank(fvs(1:nf,:),chank_size,hb.nbins(1)); +[u2,d2] = eigs(covfh2,60); d2 = diag(d2); + +figure(4); +semilogy(d,'p-'); + +figure(3);imagesc(u); + +back_v = backproj_outer_chank(fvs,u,d,chank_size); + +back_v2 = backproj_outer_chank2(fvs,u,d,chank_size); + + +%%%%%%%%%% +figure(2); +for j = 1:16, + subplot(4,4,j); + im(reshape(back_v(:,j),size(Is,1),size(Is,2))); + axis('off');title(num2str(j)); +end + +binv = linspace(-0.6,0.6,20); + +figure(4); +for j=1:16, + subplot(4,4,j); + imagesc(reshape(u(:,j),20,24));title(num2str(j));drawnow; +end + + +figure(6); +for j=1:16, + subplot(4,4,j); + plot(binv,(reshape(u(:,j),20,24)));title(num2str(j));drawnow; +end + + +%%%%%%%%%% +figure(12); + ct = round(ginput(1)); + idx = (ct(:,1)-1)*size(Is,1) + ct(:,2); + +figure(5); +for j = 1:7*2, + subplot(7,2,j); + nvv = 2*j; + dist = back_v(idx,1:nvv)*back_v(:,1:nvv)'; + im(reshape(abs(dist).^2,size(Is,1),size(Is,2)));colorbar + axis('off');title(num2str(nvv)); +end + + +a = colize_hist(fvs(1:nf,idx'),hb)'; + +dist_raw = dist_pair_chank(a,fvs,chank_size); +figure(3);im(reshape(dist_raw.^2,size(Is,1),size(Is,2))); + + + +%%%%%%%%%%%%%% +figure(12); + ct_t3 = round(ginput(5)); + idx_t3 = (ct_t3(:,1)-1)*size(Is,1) + ct_t3(:,2); + +a1 = colize_hist(fvs(1:nf,idx_t1'),hb)'; +a2 = colize_hist(fvs(1:nf,idx_t2'),hb)'; +a3 = colize_hist(fvs(1:nf,idx_t3'),hb)'; + + +%%%%%%%%%%% +figure(1); +for j=1:9, + subplot(3,3,j); + hist(back_v(:,j)) +end + diff --git a/SD-VBS/common/toolbox/toolbox_basic/filter_hist/test_evtex2.m b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/test_evtex2.m new file mode 100755 index 0000000..9e1d3e7 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/test_evtex2.m @@ -0,0 +1,136 @@ + +%%%%%%%%% test histogram on gray levels %%%%%%%%%%%%% + +%load st +%fvs = colize(Is,Is); + +nf = 1;np = 7442;nbins = 10; + +hb.sigs = 0.02*ones(1,nf); +hb.bmins= 0*ones(1,nf); +hb.bmaxs= 1*ones(1,nf); +hb.nbins= nbins*ones(1,nf); + +fh = colize_hist(fvs(1:nf,1:np),hb); + +fh_inner = fh*fh'; + +nv = nbins-1; + +[u,d] = eigs(fh_inner,nv); d = diag(d); + +figure(6); +for j=1:nv, + subplot(4,4,j); + plot(u(:,j)); + title(num2str(j)); +end + +s = 1./sqrt(d); + +back_v = (fh'*u(:,1:nv)).*(ones(np,1)*s(1:nv)'); + +figure(7); +for j=1:nv, + subplot(4,4,j); + im(reshape(back_v(:,j),size(Is,1),size(Is,2)));axis('off'); + title(num2str(j)); +end + +figure(1); +plot(d,'p-'); +figure(2); +im(u); + + +%%%%%%%%% try the joint x-I histogram bin %%%%%%%%%%%%% + +x = [1:size(Is,1)]'*ones(1,size(Is,2)); +x = reshape(x,size(Is,1),size(Is,2)); + +joint_f(:,:,1) = x; +joint_f(:,:,2) = Is; + +fvs = colize(joint_f,Is); + +nf = 2;np = 7442;nbins = [5,10]; + +hb.sigs = [4,0.02].*ones(1,nf); +hb.bmins= [1,0].*ones(1,nf); +hb.bmaxs= [size(Is,1),1].*ones(1,nf); +hb.nbins= nbins.*ones(1,nf); + +fh = colize_joint_hist(fvs,hb); +fh = reshape(fh,50,np); + +fh_inner = fh*fh'; + +nv = 30; + +[u,d] = eigs(fh_inner,nv); d = diag(d); + +figure(3); +for j=1:min(16,nv), + subplot(4,4,j); + im(reshape(u(:,j),5,10));axis('off'); + title(num2str(j)); +end + +s = 1./sqrt(d); + +back_v = (fh'*u(:,1:nv)).*(ones(np,1)*s(1:nv)'); + +figure(4); +for j=1:min(16,nv), + subplot(4,4,j); + im(reshape(back_v(:,j),size(Is,1),size(Is,2)));axis('off'); + title(num2str(j)); +end + + +%%%%%%%% + + +joint_f = []; + +joint_f(:,:,1) = Is; +joint_f(:,:,2) = ts(:,:,1); + +fvs = colize(joint_f,Is); + +nf = 2;np = 7442;nbins = [10,10]; + +hb.sigs = [0.02,0.02].*ones(1,nf); +hb.bmins= [0,-0.6].*ones(1,nf); +hb.bmaxs= [1,0.6].*ones(1,nf); +hb.nbins= nbins.*ones(1,nf); + +fh = colize_joint_hist(fvs,hb); + +fh = reshape(fh,size(fh,1)*size(fh,2),np); + +fh_inner = fh*fh'; + +nv = 30; + +[u,d] = eigs(fh_inner,nv); d = diag(d); + +figure(3); +for j=1:min(16,nv), + subplot(4,4,j); + im(reshape(u(:,j),10,10));axis('off'); + title(num2str(j)); +end + +s = 1./sqrt(d); + +back_v = (fh'*u(:,1:nv)).*(ones(np,1)*s(1:nv)'); + +figure(4); +for j=1:min(16,nv), + subplot(4,4,j); + im(reshape(back_v(:,j),size(Is,1),size(Is,2)));axis('off'); + title(num2str(j)); +end + + diff --git a/SD-VBS/common/toolbox/toolbox_basic/filter_hist/test_evtex3.m b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/test_evtex3.m new file mode 100755 index 0000000..2f245ec --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/test_evtex3.m @@ -0,0 +1,169 @@ +%%%%%%%%% test histogram on gray levels %%%%%%%%%%%%% + +%load st + +nf = 24;np = 7442;nbins = 10; +fvs = colize(ts(:,:,1:nf),Is); + +hb.sigs = 0.02*ones(1,nf); +hb.bmins= -0.6*ones(1,nf); +hb.bmaxs= 0.6*ones(1,nf); +hb.nbins= nbins*ones(1,nf); + +fh = colize_hist(fvs(1:nf,1:np),hb); + +nw = 4; +fhs = colize_histneighb(fh,Is,nw); + +%%%%%%%%%%%%%%%%%% +figure(12); + ct = round(ginput(1)); + idx = (ct(:,1)-1)*size(Is,1) + ct(:,2); + +figure(1); +subplot(1,2,1); +imagesc(reshape(fhs(:,idx),nbins,nf)) +subplot(1,2,2); +imagesc(reshape(fh(:,idx),nbins,nf)) +%%%%%%%%%% + +fh = fhs; +fhs = sqrt(fhs); + +fh_inner = fhs*fhs'; + +nv = 30; + +[u,d] = eigs(fh_inner,nv); d = diag(d); + +figure(3); +for j=1:min(16,nv), + subplot(4,4,j); + %plot(u(:,j)); + im(reshape(u(:,j),nbins,nf)); + title(num2str(j)); +end + +s = 1./sqrt(d); + +back_v = (fhs'*u(:,1:nv)).*(ones(np,1)*s(1:nv)'); + +figure(4); +for j=1:min(16,nv), + subplot(4,4,j); + im(reshape(back_v(:,j),size(Is,1),size(Is,2)));axis('off'); + title(num2str(j)); +end + +figure(1); +semilogy(d,'p-'); +%figure(2);imagesc(u); + +%%%%%%%%% +figure(12); + ct = round(ginput(1)); + idx = (ct(:,1)-1)*size(Is,1) + ct(:,2); + +figure(5); +for j = 1:min(14,nv), + subplot(7,2,j); + nvv = j; + dist = back_v(idx,1:nvv)*back_v(:,1:nvv)'; + im(reshape(abs(dist).^2,size(Is,1),size(Is,2)));colorbar + axis('off');title(num2str(nvv)); +end + + + + +%%%%%%%%% try the joint x-I histogram bin %%%%%%%%%%%%% + +x = [1:size(Is,1)]'*ones(1,size(Is,2)); +x = reshape(x,size(Is,1),size(Is,2)); + +joint_f(:,:,1) = x; +joint_f(:,:,2) = Is; + +fvs = colize(joint_f,Is); + +nf = 2;np = 7442;nbins = [5,10]; + +hb.sigs = [4,0.02].*ones(1,nf); +hb.bmins= [1,0].*ones(1,nf); +hb.bmaxs= [size(Is,1),1].*ones(1,nf); +hb.nbins= nbins.*ones(1,nf); + +fh = colize_joint_hist(fvs,hb); +fh = reshape(fh,50,np); + +fh_inner = fh*fh'; + +nv = 30; + +[u,d] = eigs(fh_inner,nv); d = diag(d); + +figure(3); +for j=1:min(16,nv), + subplot(4,4,j); + im(reshape(u(:,j),5,10));axis('off'); + title(num2str(j)); +end + +s = 1./sqrt(d); + +back_v = (fh'*u(:,1:nv)).*(ones(np,1)*s(1:nv)'); + +figure(4); +for j=1:min(16,nv), + subplot(4,4,j); + im(reshape(back_v(:,j),size(Is,1),size(Is,2)));axis('off'); + title(num2str(j)); +end + + +%%%%%%%% + + +joint_f = []; + +joint_f(:,:,1) = Is; +joint_f(:,:,2) = ts(:,:,1); + +fvs = colize(joint_f,Is); + +nf = 2;np = 7442;nbins = [10,10]; + +hb.sigs = [0.02,0.02].*ones(1,nf); +hb.bmins= [0,-0.6].*ones(1,nf); +hb.bmaxs= [1,0.6].*ones(1,nf); +hb.nbins= nbins.*ones(1,nf); + +fh = colize_joint_hist(fvs,hb); + +fh = reshape(fh,size(fh,1)*size(fh,2),np); + +fh_inner = fh*fh'; + +nv = 30; + +[u,d] = eigs(fh_inner,nv); d = diag(d); + +figure(3); +for j=1:min(16,nv), + subplot(4,4,j); + im(reshape(u(:,j),10,10));axis('off'); + title(num2str(j)); +end + +s = 1./sqrt(d); + +back_v = (fh'*u(:,1:nv)).*(ones(np,1)*s(1:nv)'); + +figure(4); +for j=1:min(16,nv), + subplot(4,4,j); + im(reshape(back_v(:,j),size(Is,1),size(Is,2)));axis('off'); + title(num2str(j)); +end + + diff --git a/SD-VBS/common/toolbox/toolbox_basic/filter_hist/test_evtex4.m b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/test_evtex4.m new file mode 100755 index 0000000..61f1307 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/test_evtex4.m @@ -0,0 +1,353 @@ + +setup_flag = 0; +cut_window_flag = 0; +run_flag = 0; +other_flag = 0; +test_flag = 1; + + +%%%%%%%%%%%%%%%%% +if setup_flag == 1, +% = readpgm('images/134035.pgm'); + +load st3 + +I_max = 255; +tex_max = 40; + +I2 = min(1,I2/I_max); +t2 = t2/tex_max; +t2 = t2.*(t2<=1) + 1*(t2>1); +t2 = t2.*(t2>=-1) + (-1)*(t2<-1); + + +end + +%%%%%%%%%% + +%% for a given sampling rate, get the index for window center +%% + +[nr,nc] = size(I2); + +hw = 3; +st_sz = 2*hw + 1; + +nr_chank = floor(nr/st_sz); +nc_chank = floor(nc/st_sz); + +id_chank = []; +for k=1+hw:st_sz:nc-hw, + for j=1+hw:st_sz:nr-hw, + id = j+(k-1)*nr; + id_chank = [id_chank,id]; + end +end + +%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%% F1 difference %%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%% + +fvs = 2*I2(:)'; fvs = fvs -1; + +nf = 1; +hb.sigs = 0.02*ones(1,nf); +hb.bmins= -1*ones(1,nf); +hb.bmaxs= 1*ones(1,nf); +hb.nbins= 10*ones(1,nf); + +fh = colize_hist(fvs(1:nf,:),hb); +fhs = colize_histnb_s(fh,I2,nw,hw); + +A = fhs'*fhs; +figure(1);im(A);colorbar; + +B = A; + +%% display %%% +figure(12); +ct = round(ginput(1)); +ct_chank(1) = round((ct(1)-hw-1)/st_sz) + 1; +ct_chank(2) = round((ct(2)-hw-1)/st_sz) + 1; + +idx = (ct_chank(:,1)-1)*nr_chank + ct_chank(:,2); + +figure(3); +im(reshape(A(idx,:),nr_chank,nc_chank));colorbar; + + + +%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%% F2 difference %%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%% + +nw = 4;hw =3; + +tnf = size(t2,3); +fst = 1; +r_id = 1; +for j=1:fst:tnf, + nf = fst; + hb.sigs = 0.02*ones(1,nf); hb.bmins= -1*ones(1,nf); + hb.bmaxs= 1*ones(1,nf); hb.nbins= 10*ones(1,nf); + + fvs = colize(t2(:,:,j:j+fst-1),I2); + fh = colize_hist(fvs,hb); + fhs = colize_histnb_s(fh,I2,nw,hw); + A = fhs'*fhs; + cm = sprintf('save F%d A fhs',r_id+1); + disp(cm);eval(cm); + clear fh; + + B = B + A; + + clear A; + + + r_id = r_id +1; +end + + +%%%%%% debug + display %%%%%%%% + +figure(6); +for j=2:30, + subplot(5,6,j); + im(t2(:,:,j-1));axis('off');title(num2str(j-1)); +end +subplot(5,6,1);im(I2);axis('off'); + + +figure(6); +B = zeros(size(A)); +for j = 1:31, + %subplot(5,6,j); + cm = sprintf('load F%d;',j); + disp(cm);eval(cm); + + fhs1 = sqrt(fhs); A = fhs1'*fhs1; +% im(reshape(A(idx,:),nr_chank,nc_chank));axis('off');title(num2str(j-1));colorbar; + B = B+A; +end + + +%%%%%% disp dist. %%%%%% +figure(12); +ct = round(ginput(1));ct_chank(1) = round((ct(1)-hw-1)/st_sz) + 1; +ct_chank(2) = round((ct(2)-hw-1)/st_sz) + 1; + +idx = (ct_chank(:,1)-1)*nr_chank + ct_chank(:,2); + +figure(2); +im(reshape(B(idx,:),nr_chank,nc_chank));axis('off');title('B');colorbar; + + + +%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%% F3 features %%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%% + +%%% Joint Intensity with filters %%%% + + +tnf = size(t2,3); + +plaatjeon = 1; +if plaatjeon, + for j=7:tnf, + cm = sprintf('!touch /disks/plaatje/scratch/jshi/FJ%d.mat',j); + disp(cm); + eval(cm);cm = sprintf('!ln -s /disks/plaatje/scratch/jshi/FJ%d.mat .',j); + disp(cm);eval(cm); + end +else + for j=1:1, + cm = sprintf('!touch ~/store/st/FJ%d.mat',j); + disp(cm);eval(cm); + cm = sprintf('!ln -s ~/store/st/FJ%d.mat .',j); + disp(cm);eval(cm); + end +end + +for j=7:tnf, + nf = 2; + hb.sigs = 0.02*ones(1,nf); hb.bmins= -1*ones(1,nf); + hb.bmaxs= 1*ones(1,nf); hb.nbins= 10*ones(1,nf); + + fvs = colize(cat(3,t2(:,:,j),I2)); + + fhs = colize_histnb_sf(fvs,I2,hb,nw,hw); + fhs = sqrt(fhs); + A = fhs'*fhs; + cm = sprintf('save FJ%d A fhs',j); + disp(cm);eval(cm); + +end + +%%%% reload data %%%%%%%%%%%%%% +B = zeros(size(A)); + +figure(3); + +for j=1:tnf, + cm = sprintf('load FJ%d;',j); + disp(cm);eval(cm); + + subplot(5,6,j); + im(reshape(A(idx,:),nr_chank,nc_chank));axis('off');title(num2str(j)); + + B = B + A; +end + +figure(2);im(reshape(B(idx,:),nr_chank,nc_chank));axis('off');title('B'); + + +%%%%%% disp dist. %%%%%% +figure(12); +ct = round(ginput(1));ct_chank(1) = round((ct(1)-hw-1)/st_sz) + 1; +ct_chank(2) = round((ct(2)-hw-1)/st_sz) + 1; +idx = (ct_chank(:,1)-1)*nr_chank + ct_chank(:,2); + +figure(2); +im(reshape(A(idx,:),nr_chank,nc_chank));axis('off');colorbar; + +%%%%%% disp Joint Hist %%%%%%%%% + +figure(12); +ct = round(ginput(1));ct_chank(1) = round((ct(1)-hw-1)/st_sz) + 1; +ct_chank(2) = round((ct(2)-hw-1)/st_sz) + 1; +idx = (ct_chank(:,1)-1)*nr_chank + ct_chank(:,2); + +figure(1); +im(reshape(fhs(:,idx),10,10));axis('off');colorbar; + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%% F4: Joint filters %%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + + +tnf = size(t2,3); + +nw = 4;hw =3; + +for scale=1:5, + for angle = 1:3, + cm = sprintf('!touch /disks/plaatje/scratch/jshi/FFJ_%d_%d_%d_%d.mat',angle,angle+3,scale,scale); + disp(cm);eval(cm); + cm = sprintf('!ln -s /disks/plaatje/scratch/jshi/FFJ_%d_%d_%d_%d.mat .',angle,angle+3,scale,scale); + disp(cm);eval(cm); + end +end + + +for scale = 1:5, + for angle = 1:3, + nf = 2; + hb.sigs = 0.02*ones(1,nf); hb.bmins= -1*ones(1,nf); + hb.bmaxs= 1*ones(1,nf); hb.nbins= 10*ones(1,nf); + + fvs = colize(cat(3,t2(:,:,(scale-1)*6+angle),... + t2(:,:,(scale-1)*6+angle+3))); + + fhs = colize_histnb_sf(fvs,I2,hb,nw,hw); + fhs = sqrt(fhs); + A = fhs'*fhs; + cm = sprintf('save FFJ_%d_%d_%d_%d A fhs',angle,angle+3,scale,scale); + disp(cm);eval(cm); + end +end + + +%%%%%%%%% load results %%%%%%%%%%% +%B = zeros(size(A)); + +figure(3); +for scale=1:5, + for angle = 1:3, + cm = sprintf('load FFJ_%d_%d_%d_%d.mat',angle,angle+3,scale,scale); + disp(cm);eval(cm); + + subplot(3,5,scale+(angle-1)*5); + im(reshape(A(idx,:),nr_chank,nc_chank)); + axis('off');title(sprintf('%d-%d,%d',angle,angle+3,scale)); + + %B = B + A; + end +end + + + + +%%% disp results + +angle = 1;scale = 1; +cm = sprintf('load FFJ_%d_%d_%d_%d.mat',angle,angle+3,scale,scale); +disp(cm);eval(cm); + + + +figure(12); +ct = round(ginput(1));ct_chank(1) = round((ct(1)-hw-1)/st_sz) + 1; +ct_chank(2) = round((ct(2)-hw-1)/st_sz) + 1; +idx = (ct_chank(:,1)-1)*nr_chank + ct_chank(:,2); + +%figure(1);im(reshape(fhs(:,idx),10,10));axis('off');%colorbar; +%figure(2);im(reshape(A(idx,:),nr_chank,nc_chank));%axis('off');%title('B'); +figure(4);im(reshape(B(idx,:),nr_chank,nc_chank));%axis('off');%title('B'); + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +%%%%%% reduction %%%%%%%%%%%%%%%%% +nv = 50; +[uB,dB] = eigs(B,nv);dB = diag(dB); + +figure(1);subplot(2,1,1);plot(dB,'p-'); +subplot(2,1,2);semilogy(dB,'p-'); + +figure(2); + +for j=1:20, + subplot(4,5,j); + im(reshape(uB(:,j),nr_chank,nc_chank));axis('off');colorbar;title(num2str(j)); +end + + +%%%%% Ncut without reduction %%%% +[uNu,dNu] = eig_decomp_v5(B,20); + +figure(1);subplot(2,1,1);plot(dNu,'p-'); +subplot(2,1,2);semilogy(dNu,'p-'); + +figure(2); +for j=2:6, + subplot(1,5,j-1); + im(reshape(-uNu(:,j),nr_chank,nc_chank));axis('off');colorbar;title(num2str(j)); +end + +%%%%%% Ncut with reduction %%%%%%%%% +nvv = 6; +B1 = uB(:,1:nvv)*uB(:,1:nvv)'; + + +[uN,dN] = eig_decomp_v5(abs(B1),20); + +figure(1);subplot(2,1,1);plot(dN,'p-'); +subplot(2,1,2);semilogy(dN,'p-'); + +figure(3); +for j=2:6, + subplot(1,5,j-1); + im(reshape(uN(:,j),nr_chank,nc_chank));axis('off');colorbar;title(num2str(j)); +end + + +%%%%%% + + + + diff --git a/SD-VBS/common/toolbox/toolbox_basic/filter_hist/test_evtex5.m b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/test_evtex5.m new file mode 100755 index 0000000..2b86e0a --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/test_evtex5.m @@ -0,0 +1,446 @@ + +setup_flag = 0; +cut_window_flag = 0; +run_flag = 0; +other_flag = 0; +test_flag = 1; + + +%%%%%%%%%%%%%%%%% +if setup_flag == 1, + +sigs = [1/sqrt(2),1,sqrt(2),2,2*sqrt(2)];r = 3;szs = round(r*3*sigs); +szs = szs(length(szs))*ones(1,length(szs)); +num_ori = 6; + +compute_flag = 0; +if compute_flag, +fnames = [134002,134007,134011,134013,130065,130038,130039,130040,130042,... + 130045,130046,130056,130068]; + +for j=1:length(fnames), + fname = sprintf('images/%d.pgm',fnames(j)); + + cm = sprintf('!touch /disks/plaatje/scratch/jshi/Fe_%d.mat',fnames(j)); + disp(cm);eval(cm); + + cm = sprintf('!ln -s /disks/plaatje/scratch/jshi/Fe_%d.mat .',fnames(j)); + disp(cm);eval(cm); + + disp(fname); + I = readpgm(fname);figure(3);im(I);title(num2str(fname));drawnow; + [text_des,filters] = compute_filter_fft(I,sigs,r,szs,num_ori); + + cm = sprintf('save Fe_%d text_des filters fname sigs r szs num_ori',fnames(j)); + disp(cm);eval(cm); + + clear text_des filters I +end + +end +else +%%%%%%%%%%%%% + fname = 134013; + + Iname = sprintf('images/%d.pgm',fname); + I = readpgm(Iname); + + cm = sprintf('load Fe_%d.mat',fname); + disp(cm);eval(cm); + + figure(1);im(I); + + + cutsz =20; + I = cutoff(I,cutsz);figure(1);im(I); + text_des = cutoff(text_des,cutsz); + + figure(2); + for j =1:30, + subplot(5,6,j);im(text_des(:,:,j));axis('off'); + end + + I1 = I(20:200,70:240); + T1 = text_des(20:200,70:240,:); + + save st_134013 I1 T1 fname sigs szs r num_ori + +end + + + +%%%%%%%%%%% normalization %%%%%%%%%%% + + +I_max = 250; +tex_max = 40; + +I1 = min(1,I1/I_max); +T1 = T1/tex_max; +T1 = T1.*(T1<=1) + 1*(T1>1); +T1 = T1.*(T1>=-1) + (-1)*(T1<-1); + + +end + +%%%%%%%%%% + +%% for a given sampling rate, get the index for window center +%% + +[nr,nc] = size(I1); + +hw = 3; +st_sz = 2*hw + 1; + +nr_chank = floor(nr/st_sz); +nc_chank = floor(nc/st_sz); + +id_chank = []; +for k=1+hw:st_sz:nc-hw, + for j=1+hw:st_sz:nr-hw, + id = j+(k-1)*nr; + id_chank = [id_chank,id]; + end +end + +%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%% F1 difference %%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%% + +fvs = 2*I1(:)'; fvs = fvs -1; + +nf = 1; +hb.sigs = 0.02*ones(1,nf); +hb.bmins= -1*ones(1,nf); +hb.bmaxs= 1*ones(1,nf); +hb.nbins= 10*ones(1,nf); +nw = 4;hw =3; + +fh = colize_hist(fvs(1:nf,:),hb); +fhs = colize_histnb_s(fh,I1,nw,hw); + +fhs = sqrt(fhs); +A = fhs'*fhs; +figure(2);im(A);colorbar; + +B = A; + +%% display %%% +figure(2); +ct = round(ginput(1)); +ct_chank(1) = round((ct(1)-hw-1)/st_sz) + 1; +ct_chank(2) = round((ct(2)-hw-1)/st_sz) + 1; + +idx = (ct_chank(:,1)-1)*nr_chank + ct_chank(:,2); + +figure(3);im(reshape(A(idx,:),nr_chank,nc_chank));colorbar; + +subplot(1,2,1);im(reshape(A1(idx,:),nr_chank,nc_chank));colorbar; +subplot(1,2,2);im(reshape(A2(idx,:),nr_chank,nc_chank));colorbar; + + +%%%%%%%%%% +save_flag = 0; + +fn = 134013; + +if save_flag, + cm = sprintf('save F1_%d fhs hw nw nr_chank nc_chank',fn); + disp(cm);eval(cm); + +end + +load_flag = 1; +if load_flag, + cm = sprintf('load F1_%d',fn); + disp(cm);eval(cm); + + A=fhs'*fhs; +end + + +%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%% F2 difference %%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%% + +nw = 4;hw =3; + +tnf = size(T1,3); +fst = 1; + +for j=1:fst:1, + nf = fst; + hb.sigs = 0.02*ones(1,nf); hb.bmins= -1*ones(1,nf); + hb.bmaxs= 1*ones(1,nf); hb.nbins= 15*ones(1,nf); + + fvs = colize(T1(:,:,j:j+fst-1),I1); + fh = colize_hist(fvs,hb); + fhs = colize_histnb_s(fh,I1,nw,hw); + fhs = sqrt(fhs); + + A = fhs'*fhs; + + cm = sprintf('save F2_%d_%d fhs hw nw nr_chank nc_chank',j,fn); + disp(cm);eval(cm); + clear fh; + + B = B + A; + + clear A; + +end + + +%%%%%% debug + display %%%%%%%% + +figure(6); +for j=2:30, + subplot(5,6,j); + im(T1(:,:,j-1));axis('off');title(num2str(j-1)); +end +subplot(5,6,1);im(I1);axis('off'); + + +figure(6); +B = zeros(size(A)); +for j = 1:31, + %subplot(5,6,j); + cm = sprintf('load F%d;',j); + disp(cm);eval(cm); + + fhs1 = sqrt(fhs); A = fhs1'*fhs1; +% im(reshape(A(idx,:),nr_chank,nc_chank));axis('off');title(num2str(j-1));colorbar; + B = B+A; +end + + +%%%%%% disp dist. %%%%%% +weight= 5; +A = weight*B+B2; + +figure(1); +ct = round(ginput(1));ct_chank(1) = round((ct(1)-hw-1)/st_sz) + 1; +ct_chank(2) = round((ct(2)-hw-1)/st_sz) + 1; +idx = (ct_chank(:,1)-1)*nr_chank + ct_chank(:,2); + +figure(2); +im(reshape(A(idx,:),nr_chank,nc_chank));axis('off');colorbar; %title('B'); +%figure(3); + + +save_flag = 0; +if save_flag , + B2 = B; + save tmp B2 nr_chank nc_chank +end + +%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%% F3 features %%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%% + +%%% Joint Intensity with filters %%%% + + +tnf = size(T1,3); + +plaatjeon = 1; +if plaatjeon, + for j=7:tnf, + cm = sprintf('!touch /disks/plaatje/scratch/jshi/FJ%d.mat',j); + disp(cm); + eval(cm);cm = sprintf('!ln -s /disks/plaatje/scratch/jshi/FJ%d.mat .',j); + disp(cm);eval(cm); + end +else + for j=1:1, + cm = sprintf('!touch ~/store/st/FJ%d.mat',j); + disp(cm);eval(cm); + cm = sprintf('!ln -s ~/store/st/FJ%d.mat .',j); + disp(cm);eval(cm); + end +end + +for j=7:tnf, + nf = 2; + hb.sigs = 0.02*ones(1,nf); hb.bmins= -1*ones(1,nf); + hb.bmaxs= 1*ones(1,nf); hb.nbins= 10*ones(1,nf); + + fvs = colize(cat(3,T1(:,:,j),I1)); + + fhs = colize_histnb_sf(fvs,I1,hb,nw,hw); + fhs = sqrt(fhs); + A = fhs'*fhs; + cm = sprintf('save FJ%d A fhs',j); + disp(cm);eval(cm); + +end + +%%%% reload data %%%%%%%%%%%%%% +B = zeros(size(A)); + +figure(3); + +for j=1:tnf, + cm = sprintf('load FJ%d;',j); + disp(cm);eval(cm); + + subplot(5,6,j); + im(reshape(A(idx,:),nr_chank,nc_chank));axis('off');title(num2str(j)); + + B = B + A; +end + +figure(2);im(reshape(B(idx,:),nr_chank,nc_chank));axis('off');title('B'); + + +%%%%%% disp dist. %%%%%% +figure(12); +ct = round(ginput(1));ct_chank(1) = round((ct(1)-hw-1)/st_sz) + 1; +ct_chank(2) = round((ct(2)-hw-1)/st_sz) + 1; +idx = (ct_chank(:,1)-1)*nr_chank + ct_chank(:,2); + +figure(2); +im(reshape(A(idx,:),nr_chank,nc_chank));axis('off');colorbar; + +%%%%%% disp Joint Hist %%%%%%%%% + +figure(12); +ct = round(ginput(1));ct_chank(1) = round((ct(1)-hw-1)/st_sz) + 1; +ct_chank(2) = round((ct(2)-hw-1)/st_sz) + 1; +idx = (ct_chank(:,1)-1)*nr_chank + ct_chank(:,2); + +figure(1); +im(reshape(fhs(:,idx),10,10));axis('off');colorbar; + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%% F4: Joint filters %%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + + +tnf = size(T1,3); + +nw = 4;hw =3; + +for scale=1:5, + for angle = 1:3, + cm = sprintf('!touch /disks/plaatje/scratch/jshi/FFJ_%d_%d_%d_%d.mat',angle,angle+3,scale,scale); + disp(cm);eval(cm); + cm = sprintf('!ln -s /disks/plaatje/scratch/jshi/FFJ_%d_%d_%d_%d.mat .',angle,angle+3,scale,scale); + disp(cm);eval(cm); + end +end + + +for scale = 1:5, + for angle = 1:3, + nf = 2; + hb.sigs = 0.02*ones(1,nf); hb.bmins= -1*ones(1,nf); + hb.bmaxs= 1*ones(1,nf); hb.nbins= 10*ones(1,nf); + + fvs = colize(cat(3,T1(:,:,(scale-1)*6+angle),... + T1(:,:,(scale-1)*6+angle+3))); + + fhs = colize_histnb_sf(fvs,I1,hb,nw,hw); + fhs = sqrt(fhs); + A = fhs'*fhs; + cm = sprintf('save FFJ_%d_%d_%d_%d A fhs',angle,angle+3,scale,scale); + disp(cm);eval(cm); + end +end + + +%%%%%%%%% load results %%%%%%%%%%% +%B = zeros(size(A)); + +figure(3); +for scale=1:5, + for angle = 1:3, + cm = sprintf('load FFJ_%d_%d_%d_%d.mat',angle,angle+3,scale,scale); + disp(cm);eval(cm); + + subplot(3,5,scale+(angle-1)*5); + im(reshape(A(idx,:),nr_chank,nc_chank)); + axis('off');title(sprintf('%d-%d,%d',angle,angle+3,scale)); + + %B = B + A; + end +end + + + + +%%% disp results + +angle = 1;scale = 1; +cm = sprintf('load FFJ_%d_%d_%d_%d.mat',angle,angle+3,scale,scale); +disp(cm);eval(cm); + + + +figure(12); +ct = round(ginput(1));ct_chank(1) = round((ct(1)-hw-1)/st_sz) + 1; +ct_chank(2) = round((ct(2)-hw-1)/st_sz) + 1; +idx = (ct_chank(:,1)-1)*nr_chank + ct_chank(:,2); + +%figure(1);im(reshape(fhs(:,idx),10,10));axis('off');%colorbar; +%figure(2);im(reshape(A(idx,:),nr_chank,nc_chank));%axis('off');%title('B'); +figure(4);im(reshape(B(idx,:),nr_chank,nc_chank));%axis('off');%title('B'); + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +%%%%%% reduction %%%%%%%%%%%%%%%%% +nv = 50; +[uA,dA] = eigs(A,nv);dA = diag(dA); + +figure(4);suAplot(2,1,1);plot(dA,'p-'); +subplot(2,1,2);semilogy(dA,'p-'); + +figure(3); + +for j=1:20, + subplot(4,5,j); + im(reshape(uA(:,j),nr_chank,nc_chank));axis('off');colorbar;title(num2str(j)); +end + + +%%%%% Ncut without reduction %%%% + +[uNu,dNu] = eig_decomp_v5(A,20); + +figure(4);subplot(2,1,1);plot(dNu,'p-'); +subplot(2,1,2);semilogy(dNu,'p-'); + +figure(3); +for j=2:6, + subplot(1,5,j-1); + im(reshape(-uNu(:,j),nr_chank,nc_chank));axis('off');colorbar;title(num2str(j)); +end + +%%%%%% Ncut with reduction %%%%%%%%% +nvv = 7; +A1 = uA(:,1:nvv)*uA(:,1:nvv)'; + + +[uN,dN] = eig_decomp_v5(abs(A1),20); + +figure(1);subplot(2,1,1);plot(dN,'p-'); +subplot(2,1,2);semilogy(dN,'p-'); + +figure(3); +for j=2:6, + subplot(1,5,j-1); + im(reshape(uN(:,j),nr_chank,nc_chank));axis('off');colorbar;title(num2str(j)); +end + + +%%%%%% + + + + diff --git a/SD-VBS/common/toolbox/toolbox_basic/filter_hist/test_motion.m b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/test_motion.m new file mode 100755 index 0000000..91c97f9 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/test_motion.m @@ -0,0 +1,117 @@ + +im_sz = [40,40]; + +ob_szh = [6,3]; + +ob_c = [15,12]; + +bg_color = 0.2; + +ob_color = 0.8; + +mag = 0.2; + +I_bg = bg_color + mag*randn(im_sz); + +I_obj = ob_color + mag*randn(2*ob_szh+1); + + +w = 3; + +v5 = 1; +Js = []; + +if ~v5, + for j=1:5, + fc = sprintf('J%d = I_bg;',j); + eval(fc); + + fc = sprintf('J%d(ob_c(1)-ob_szh(1):ob_c(1)+ob_szh(1),ob_c(2)-ob_szh(2):ob_c(2)+ob_szh(2)) = I_obj;',j); + eval(fc); + + ob_c = ob_c+[0,2]; + end +else + nf = 4; + for j = 1:nf, + + J = I_bg; + J(ob_c(1)-ob_szh(1):ob_c(1)+ob_szh(1),ob_c(2)-ob_szh(2):ob_c(2)+ob_szh(2)) = I_obj; + + if (j==1), + [gy,gx] = grad(J,w); + end + + ob_c = ob_c+[0,2]; + + Jw = cutoff(J,w); + Js(:,:,j) = Jw; + end + +end + +[nr,nc] = size(gx); + +for j=1:nf, + subplot(1,nf,j); + imagesc(Js(:,:,j));axis('tightequal'); +end + + +writepnm5('test_motion.pnm',Js); +writepnm5('test_motion_gx.pnm',gx); +writepnm5('test_motion_gy.pnm',gy); +%imagesc(J1);colorbar; + + +inpara = [2,5,0.5,1,0.5]; + +[A,D,Ipara] = cas('test_motion',inpara); + +B= A+ A'; +clear A; + +%BB = B(1:19^2,19^2+(1:19^2)); +%imagesc(BB); + +[v,d] = eigs(B);d = diag(d); + +k = 2; + +figure(1); +%nf = 5; + +nr = nr-5; +nc = nc-5; + +n = nr* nc; + +for j =1:nf, + subplot(1,nf,j); + imagesc(reshape(v((j-1)*n+(1:n),k).*D(1:n),nr,nc)');axis('tightequal'); +end + +%%%%% + + +figure(3); +T = readpnm('test_motion.pnm'); +nf = size(T,3); +for j=1:nf, + subplot(1,nf,j); + imagesc(T(:,:,j));axis('tightequal'); +end + + +figure(2); +Gx = readpnm('test_motion_gx.pnm'); + +[nr,nc] =size(Gx); +n = nr*nc; + +imagesc(reshape(B(n+1:2*n,6*nc+7),nc,nr)');colorbar + + + + + diff --git a/SD-VBS/common/toolbox/toolbox_basic/filter_hist/test_motion2.m b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/test_motion2.m new file mode 100755 index 0000000..2959fa8 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/test_motion2.m @@ -0,0 +1,127 @@ + +im_sz = [40,40]; + +ob_szh = [4,3]; + +ob_c = [12,12]; + +ob_co = [30,28]; + +bg_color = 0.2; + +ob_color = 0.8; + +mag = 0.2; + +I_bg = bg_color + mag*randn(im_sz); + +I_obj = ob_color + mag*randn(2*ob_szh+1); + + +w = 3; + +v5 = 1; +Js = []; + +if ~v5, + for j=1:5, + fc = sprintf('J%d = I_bg;',j); + eval(fc); + + fc = sprintf('J%d(ob_c(1)-ob_szh(1):ob_c(1)+ob_szh(1),ob_c(2)-ob_szh(2):ob_c(2)+ob_szh(2)) = I_obj;',j); + eval(fc); + + fc = sprintf('J%d(ob_co(1)-ob_szh(1):ob_co(1)+ob_szh(1),ob_co(2)-ob_szh(2):ob_co(2)+ob_szh(2)) = I_obj;',j); + eval(fc); + + ob_c = ob_c+[0,2]; + ob_co = ob_co-[0,2]; + + end +else + nf = 4; + for j = 1:nf, + + J = I_bg; + J(ob_c(1)-ob_szh(1):ob_c(1)+ob_szh(1),ob_c(2)-ob_szh(2):ob_c(2)+ob_szh(2)) = I_obj; + J(ob_co(1)-ob_szh(1):ob_co(1)+ob_szh(1),ob_co(2)-ob_szh(2):ob_co(2)+ob_szh(2)) = I_obj; + + if (j==1), + [gy,gx] = grad(J,w); + end + + ob_c = ob_c+[0,2]; + ob_co = ob_co-[0,2]; + + Jw = cutoff(J,w); + Js(:,:,j) = Jw; + end + +end + +[nr,nc] = size(gx); + +for j=1:nf, + subplot(1,nf,j); + imagesc(Js(:,:,j));axis('tightequal'); +end + + +writepnm5('test_motion.pnm',Js); +writepnm5('test_motion_gx.pnm',gx); +writepnm5('test_motion_gy.pnm',gy); +%imagesc(J1);colorbar; + + +inpara = [2,5,0.5,1,0.5]; + +[A,D,Ipara] = cas('test_motion',inpara); + +B= A+ A'; +clear A; + +%BB = B(1:19^2,19^2+(1:19^2)); +%imagesc(BB); + +[v,d] = eigs(B);d = diag(d); + +k = 2; + +figure(1); +%nf = 5; + +nr = nr-5; +nc = nc-5; + +n = nr* nc; + +for j =1:nf, + subplot(1,nf,j); + imagesc(reshape(v((j-1)*n+(1:n),k).*D(1:n),nr,nc)');axis('tightequal'); +end + +%%%%% + + +figure(3); +T = readpnm('test_motion.pnm'); +nf = size(T,3); +for j=1:nf, + subplot(1,nf,j); + imagesc(T(:,:,j));axis('tightequal'); +end + + +figure(2); +Gx = readpnm('test_motion_gx.pnm'); + +[nr,nc] =size(Gx); +n = nr*nc; + +imagesc(reshape(B(n+1:2*n,6*nc+7),nc,nr)');colorbar + + +%%%%%%%%%%%%% + + +K = zeros(im_sz); diff --git a/SD-VBS/common/toolbox/toolbox_basic/filter_hist/test_period.m b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/test_period.m new file mode 100755 index 0000000..2994d15 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/test_period.m @@ -0,0 +1,58 @@ +flag = 2; + +if flag ==1, + +ws = [50,50]; + +figure(1);J = get_win(I,ginput(1),ws); +figure(4);imagesc(J); + +J = J - mean(mean(reshape(J,prod(size(J)),1))); +X = fftshift(fft2(J)); + +figure(3);imagesc(abs(X));colorbar +figure(2);mesh(abs(X)); + +else + +fn = '1.pgm'; + +% spatial gaussian parameter +xscale = 1; + +% half size of the neighbourhood +xnb = 5; + +% setting the the HSV gaussian parameter:[h s v] +Iscale = [0.01]; + +Input_para = [xscale,xnb,Iscale]; + +% compute the lower half the association matrix +[A,D,Ipara] = compute_A_pgm(fn,Input_para); + +nr = Ipara(1);nc = Ipara(2); + +B = A+A'; +clear A; + + +% eigen decompostion +options.tol = 1e-4; +num_eig_v = 10; +fprintf('doing eigs ...\n'); +[v,d] = eigs(B,num_eig_v,options); + +k = 1;imagesc(reshape(v(:,k).*D,nc,nr)');colorbar + + +end + + + + + + + + + diff --git a/SD-VBS/common/toolbox/toolbox_basic/filter_hist/test_text.m b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/test_text.m new file mode 100755 index 0000000..4cc5759 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/test_text.m @@ -0,0 +1,434 @@ + + +%case = 1; + +read_flag = 1; +compute_flag = 0; +load_flag = 0; +decomp_flag = 0; +hist_flag = 0; + +test_real = 0; + + +if read_flag, +if caseid == 1, + ifn = 'images/130049.pgm'; +elseif caseid == 2, + ifn = 'images/130055.pgm'; +elseif caseid == 3, + ifn = 'images/130056.pgm'; +elseif caseid == 4, + ifn = 'images/130057.pgm'; +elseif caseid == 5, + ifn = 'images/130060.pgm'; +elseif caseid == 6, + ifn = 'images/130061.pgm'; +elseif caseid == 7, + ifn = 'images/130062.pgm'; +elseif caseid == 8, + ifn = 'images/130065.pgm'; +elseif caseid == 9, + ifn = 'images/130066.pgm'; +elseif caseid == 10, + ifn = 'images/130068.pgm'; +elseif caseid == 11, + ifn = 'images/130070.pgm'; +else + ifn = 'images/130070.pgm'; +end + +I = readpgm(ifn); +figure(1); +imagesc(I);colormap(gray);drawnow; +axis('tightequal'); + +end + +%%%%% load %%% + +if load_flag, + fn = sprintf('load cresult_%d;',caseid); + eval(fn); +end + + +%%%%%%%%%%%%% compute %%%%%%%%%%% +sig = 0.5; +r = 3; +sz = 15; +Iw = cutoff(I,0.5*sz); +figure(1);imagesc(Iw); +axis('image'); + +if compute_flag, + +as = 0:30:150; + +Cresult = []; + +for j = 1:length(as), + fprintf('.'); + angle = as(j); + + g = doog2( sig,r,angle,sz); + + g = g - mean(reshape(g,prod(size(g)),1)); + + g = g/sum(sum(abs(g))); + + c = conv2(I,g,'valid'); + + Cresult(:,:,j) = c; +end + + +fprintf('\n'); + + +figure(2); + +subplot(2,3,1); +imagesc(Cresult(:,:,1).^2);axis('tightequal');colorbar + +subplot(2,3,2); +imagesc(Cresult(:,:,2).^2);axis('tightequal');colorbar + +subplot(2,3,3); +imagesc(Cresult(:,:,3).^2);axis('tightequal');colorbar + +subplot(2,3,4); +imagesc(Cresult(:,:,4).^2);axis('tightequal');colorbar + +subplot(2,3,5); +imagesc(Cresult(:,:,5).^2);axis('tightequal');colorbar + +subplot(2,3,6); +imagesc(Cresult(:,:,6).^2);axis('tightequal');colorbar + +Cs = []; +Mcs = []; +for j=1:length(as), + Cs(:,:,j) = reduce(reduce(abs(Cresult(:,:,j)))); + + Mcs = [Mcs,max(max(Cs(:,:,j)))]; + +end + +ms = max(Mcs); + +figure(3); +for j=1:6, + fn = sprintf('Cs(:,:,%d) = Cs(:,:,%d)/ms;',j,j); + eval(fn); + fn = sprintf('subplot(2,3,%d);imagesc(Cs(:,:,%d));',j,j); + eval(fn);axis('tightequal');colorbar +end + +fn = sprintf('save cresult_%d.mat Cresult Cs',caseid); +disp(fn); +eval(fn); + +end + +%%%%%%%%%%%%%%%%% decomp %%%%%%%%%%%% + + +if decomp_flag, + +%writepnm5('txt_2.pnm',Cs); + +%writepnm5('130068.pnm',Cs); + + +%I_scale = 0.0025; +%X_scale = 3^2; +%[A,D,Ipara] = compute_A_sparmul2(10,I_scale,X_scale); + + +I_scale = 0.02; +X_scale = 2; +[A,D,Ipara] = compute_A_pnm('130068.pnm',[X_scale,I_scale]); + +nr = Ipara(1);nc = Ipara(2); +imagesc(reshape(D,nc,nr)');colorbar; + +B = A+A';clear A; + +options.tol = 1e-7; + +[v,d] = eigs(B,9,options); + +figure(4); +k = 1; imagesc(reshape(v(:,k).*D,nc,nr)'); + +end + + +%%%% histogram %%%% + +%hist_flag = 1; + +%figure(1);imagesc(Iw);axis('image'); +if hist_flag ==1, + + +ws = [12,12]; + +figure(7); + +cs = ginput(1); + +cs = 10*(cs-1)+w/2; + +%cs(1,:) = w+(floor((cs(1,:)-w)/gap)*gap); +%cs(2,:) = w+(floor((cs(2,:)-w)/gap)*gap); + +J = get_win(Iw,cs(1,:),ws); +Jbar = get_win5(Cresult,cs(1,:),ws); + + +figure(2); +subplot(3,3,1);imagesc(J);colorbar +for j=1:6,subplot(3,3,1+j);imagesc(abs(Jbar(:,:,j)));colorbar; end + +[hists,bins] = get_hist(J,Jbar);show_hist(hists,bins,4); +cumhists = get_cumhist(hists);show_cumhist(cumhists,bins,6,1,'b-o'); + +J2 = get_win(Iw,cs(2,:),ws); +Jbar2 = get_win5(Cresult,cs(2,:),ws); + +figure(3); +subplot(3,3,1);imagesc(J2);colorbar +for j=1:6,subplot(3,3,1+j);imagesc(abs(Jbar2(:,:,j)));colorbar; end + +[hists2,bins2] = get_hist(J2,Jbar2);show_hist(hists2,bins2,5); +cumhists2 = get_cumhist(hists2);show_cumhist(cumhists2,bins2,6,0,'r-*'); + +diff.inten = max(abs(cumhists.inten-cumhists2.inten)); +diff.mag = max(abs(cumhists.mag-cumhists2.mag)); +diff.text = max(max(abs(cumhists.text-cumhists2.text))); + +figure(7); + +disp([diff.inten,diff.mag,diff.text]); +maxdiff = max([diff.inten,diff.mag,diff.text]); +disp(1-sigmoid(diff.inten,0.22,0.02)); + + +if 0, +%A = pair_dist_text(Iw,Cresult,15); + +r =4;w = 22;gap = 5;sig_x= 20.0; +inpara = [r,w,gap,sig_x,0.16,0.2,0.2]; +[Cum,tm] = cAh(Iw,mag,abs(Cresult),inpara); + +[Cum,Nb,Nc] = cAh4(Iw,mag,abs(Cresult),inpara); + + +B = A+ A';clear A; + +figure(1); +c = ginput(1); +cx = floor(c(1)/gap); +cy = floor(c(2)/gap); +[cx,cy] +figure(7) +imagesc(reshape(B(cy*Cum(1)+cx,:),Cum(1),Cum(2))');colorbar + + +cutoff = [0.22,0.2,0.2]; +sig_hist = [0.02,0.04,0.05]; + +inpara2 = [r,5,cutoff,sig_hist]; +[A,D] = compute_A_hist3(tm,Cum,inpara2); + +B = A+A';clear A; +imagesc(reshape(D,Cum(1),Cum(2))'); + + +[v,d] = eigs(B); + + +end + +end + +%%%%%%%%%%%%% trans_texture %%%%%%%%%%%% +trans_text = 0; + + +if trans_text, + figure(1); + cs = ginput(1); + + ws = [40,40]; + + J = get_win(Iw,cs(1,:),ws); + Jbar = get_win5(Cresult,cs(1,:),ws); + Jmag = get_win(mag,cs(1,:),ws); + + figure(3);imagesc(J); + + figure(3); + for j=1:6, + subplot(2,3,j);imagesc(abs(Jbar(:,:,j)));axis('image');colorbar; + end + + f= abs(Jbar(40,38,:)); + g= abs(Jbar(40,47,:)); + + dot(f,g)/max(dot(f,f),dot(g,g)) + + ff = myinterp(f,10); gg = myinterp(g,10); + dot(ff,gg)/max(dot(ff,ff),dot(gg,gg)) + + cum = mc_corr(ff,gg,[-6,6]); + max(cum)/max(dot(f,f),dot(g,g)) + + + center = [40,35]; + + f = squeeze(abs(Jbar(center(1),center(2),:))); + ff = myinterp(f,10); + mag_ff = dot(ff,ff); + mag_c = Jmag(center(1),center(2)); + dy = 0; + + cor_cofs = []; + mags = []; + for dx = -15:15, + g = squeeze(abs(Jbar(center(1)+dy,center(2)+dx,:))); + gg = myinterp(g,10); + + cum = mc_corr(ff,gg,[-6,6]); + cor_cofs = [cor_cofs,max(cum)/max(mag_ff,dot(gg,gg))]; + + mags =[mags,max(mag_c,Jmag(center(1)+dy,center(2)+dx,:))]; + + end + + simulation_on =0; + + if simulation_on, + + sz = [161,161] + SI = zeros(sz); + + for i=2:18:sz(1), + SI(i:i+2,:) = 1+SI(i:i+2,:); + end + + imagesc(SI);axis('image'); + + tmp1 = mimrotate(SI,90,'nearest','crop'); + tmp2 = mimrotate(SI,45,'nearest','crop'); + + ly = round(0.7*sz(1)); + lx = round(0.7*sz(1)); + sy = round(0.16*sz(1)); + sx = round(0.2*sz(2)); + TI = [tmp1(1:ly,1:lx),tmp2(sy+1:sy+ly,sy+1:sy+round(0.4*lx))]; + + TI = TI+0.04*randn(size(TI)); + + %sig = 1/sqrt(2);r = 3;sz = round(r*3*sig); + + sigs = [1/sqrt(2),1,sqrt(2),2,2*sqrt(2)];r = 3;szs = round(r*3*sigs); + [text_des,TIw] = compute_filter(TI,sigs,r,szs); + figure(2);imagesc(TIw);axis('image'); + + figure(3); + im5(abs(text_des),2,3); + + text_des = abs(text_des); + + text_des = T1; + + numband = size(text_des,3); r = 10; + sig_x = 90; sig_inten = 0.15; sig_tex = 0.01;w_inten = 0.03; + para = [numband,r,sig_x,sig_inten,sig_tex,w_inten]; + + [A,D,Ipara] = compute_A_text(TIw,text_des,para); + nr = Ipara(1);nc = Ipara(2); + B = A+A'; clear A; + + figure(2); + cs = ginput(1); + cs = round(cs);id = cs(2)*nc+cs(1); + + figure(4); + imagesc(reshape(B(id,:),nc,nr)');axis('image');colorbar + + [v,d] = eigs(B); + figure(4);imagesc(reshape(D.*v(:,1),nc,nr)');axis('image'); + + end + +end + +if test_real == 1, + sigs = [1/sqrt(2),1,sqrt(2),2,2*sqrt(2)];r = 3;szs = round(r*3*sigs); + text_des = compute_filter(I,sigs,r,szs); + + text_des = abs(text_des); +%save filter_3.mat + + %%%% cutoff margins, + margin = 6+10; + + Iw = cutoff(I,margin); + + T1= reshape(text_des,size(text_des,1),size(text_des,2),size(text_des,3)*size(text_des,4)); + T1 = cutoff(T1,margin); + + %%%%% reduce resolution + + Iwp = compact(Iw,4); + + T1 = reduce_all(T1); + T1 = reduce_all(T1); + +% T1 = T1/70; + + % writepnm5('test6_image.pnm',Iwp);writepnm5('test6_filter.pnm',T1); + + numband = size(T1,3); r = 2; + sig_x = 20; sig_inten = 0.15; sig_tex = 0.01;w_inten = 0.01; + para = [numband,r,sig_x,sig_inten,sig_tex,w_inten]; + + [A,D,Ipara] = compute_A_text(Iwp,T1,para); + nr = Ipara(1);nc = Ipara(2); + figure(4);imagesc(reshape(D,nc,nr)');axis('image'); + drawnow; + + + numband = 6; + r = 5; sig_x = 20.0; + sig_tex = 0.01; w_inten = 0.01; w = 2; + para = [numband,r,sig_x,sig_tex,w_inten,w,size(T1,2)]; + + [A,D,Ipara] = compute_A_text2(Iw,T1(:,:,1:numband)/70,para); + nr = Ipara(1);nc = Ipara(2); + + + + B = A+A'; clear A; + + + figure(2); + cs = ginput(1); + cs = floor(cs/4)+1;id = cs(2)*nc+cs(1); + + figure(4); + imagesc(reshape(B(id,:),nc,nr)');axis('image');colorbar + + +end + + + + + + + diff --git a/SD-VBS/common/toolbox/toolbox_basic/filter_hist/tmp.m b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/tmp.m new file mode 100755 index 0000000..b932912 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/tmp.m @@ -0,0 +1,68 @@ + +sw = 3; +gap = 2*sw+1; + +nw = 6; + +for j=1:20, + l = max(0,j-1-nw); +% l = max(0,j-1-2*nw); + rs(j) = ceil((l-sw)/gap) + 1; + l = min(20,j-1+nw); +% l = min(20,j-1); + re(j) = floor((l-sw)/gap) +1; +end + +plot([1:20],rs,'p-',[1:20],re,'rp-') + + +%%%%%%%% + +bin_max = 1.0; +bin_min = -1.0; +num_bin = 30; +sig = 0.2; + +data = 0.482; + +inc = (bin_max-bin_min)/num_bin; + +bs = -100; +be = bin_min+inc; +b = []; + +for j=1:num_bin, + + b(j) = tmp1(bs,be,data,sig); + bs = be; + be= be+inc; +end +plot(b,'p-'); + + + +bmin = -1; + +inc = 0.2; +a = 0.1; +b = -1250; +ovs = 625; + +bs = bmin; +be = bs+inc; + +data = -0.482; + +for j=1:10, + tmp = bs-data; + fs = exp(-(tmp*tmp*ovs)); + ks = b*tmp; + + tmp = be-data; + fe = exp(-(tmp*tmp*ovs)); + ke = b*tmp; + + bin(j) = fs*(2+a*ks) + fe*(2-a*ke); + bs = be; + be = be+inc; +end diff --git a/SD-VBS/common/toolbox/toolbox_basic/filter_hist/tmp1.m b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/tmp1.m new file mode 100755 index 0000000..db5dbc1 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/tmp1.m @@ -0,0 +1,25 @@ +function d = tmp1(bs,be,data,sig) + +sig = sig^2; + +if 1, +a = (bs+be)*0.5; +d = (a-bs)*(exp(-(bs-data)^2/sig) + exp(-(a-data)^2/sig)) + ... + (be-a)*(exp(-(a-data)^2/sig) + exp(-(be-data)^2/sig)); +d = d*2/sqrt(pi); +else + +a = (be-bs)/2; + +h1 = exp(-(bs-data)^2/sig); +h2 = exp(-(be-data)^2/sig); + +k1 = -2*(bs-data)/sig; +k2 = -2*(be-data)/sig; + +d = a*(h1*(2+2*a*k1) + h2*(2-2*a*k2)); +d = d*2/sqrt(pi); + +end + + diff --git a/SD-VBS/common/toolbox/toolbox_basic/filter_hist/tmp2.m b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/tmp2.m new file mode 100755 index 0000000..b361cdc --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/tmp2.m @@ -0,0 +1,17 @@ +function d = tmp2(bs,be,data,sig) + +sig = sig^2; + + +a = (be-bs)/2; + +h1 = exp(-(bs-data)^2/sig); +h2 = exp(-(be-data)^2/sig); + +k1 = -2*(bs-data)/sig; +k2 = -2*(be-data)/sig; + +d = (h1*(2+2*a*k1) + h2*(2-2*a*k2)); +%d = a*d*2/sqrt(pi); + + diff --git a/SD-VBS/common/toolbox/toolbox_basic/filter_hist/tmp3.m b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/tmp3.m new file mode 100755 index 0000000..c1bffd9 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/tmp3.m @@ -0,0 +1,126 @@ +function result = erfcore(x,jint) +%ERFCORE Core algorithm for error functions. +% erf(x) = erfcore(x,0) +% erfc(x) = erfcore(x,1) +% erfcx(x) = exp(x^2)*erfc(x) = erfcore(x,2) + +% C. Moler, 2-1-91. +% Copyright (c) 1984-96 by The MathWorks, Inc. +% $Revision: 5.7 $ $Date: 1996/10/28 20:57:59 $ + +% This is a translation of a FORTRAN program by W. J. Cody, +% Argonne National Laboratory, NETLIB/SPECFUN, March 19, 1990. +% The main computation evaluates near-minimax approximations +% from "Rational Chebyshev approximations for the error function" +% by W. J. Cody, Math. Comp., 1969, PP. 631-638. + + if ~isreal(x), + error('Input argument must be real.') + end + result = repmat(NaN,size(x)); +% +% evaluate erf for |x| <= 0.46875 +% + xbreak = 0.46875; + k = find(abs(x) <= xbreak); + if ~isempty(k) + a = [3.16112374387056560e00; 1.13864154151050156e02; + 3.77485237685302021e02; 3.20937758913846947e03; + 1.85777706184603153e-1]; + b = [2.36012909523441209e01; 2.44024637934444173e02; + 1.28261652607737228e03; 2.84423683343917062e03]; + + y = abs(x(k)); + z = y .* y; + xnum = a(5)*z; + xden = z; + for i = 1:3 + xnum = (xnum + a(i)) .* z; + xden = (xden + b(i)) .* z; + end + result(k) = x(k) .* (xnum + a(4)) ./ (xden + b(4)); + if jint ~= 0, result(k) = 1 - result(k); end + if jint == 2, result(k) = exp(z) .* result(k); end + end +% +% evaluate erfc for 0.46875 <= |x| <= 4.0 +% + k = find((abs(x) > xbreak) & (abs(x) <= 2.)); + if ~isempty(k) + c = [5.64188496988670089e-1; 8.88314979438837594e00; + 6.61191906371416295e01; 2.98635138197400131e02; + 8.81952221241769090e02; 1.71204761263407058e03; + 2.05107837782607147e03; 1.23033935479799725e03; + 2.15311535474403846e-8]; + d = [1.57449261107098347e01; 1.17693950891312499e02; + 5.37181101862009858e02; 1.62138957456669019e03; + 3.29079923573345963e03; 4.36261909014324716e03; + 3.43936767414372164e03; 1.23033935480374942e03]; + + y = abs(x(k)); + xnum = c(9)*y; + xden = y; + for i = 1:7 + xnum = (xnum + c(i)) .* y; + xden = (xden + d(i)) .* y; + end + result(k) = (xnum + c(8)) ./ (xden + d(8)); + if jint ~= 2 + z = fix(y*16)/16; + del = (y-z).*(y+z); + result(k) = exp(-z.*z) .* exp(-del) .* result(k); + end + end +% +% evaluate erfc for |x| > 4.0 +% + k = find(abs(x) > 2.0); + if ~isempty(k) +if 0, + p = [3.05326634961232344e-1; 3.60344899949804439e-1; + 1.25781726111229246e-1; 1.60837851487422766e-2; + 6.58749161529837803e-4; 1.63153871373020978e-2]; + q = [2.56852019228982242e00; 1.87295284992346047e00; + 5.27905102951428412e-1; 6.05183413124413191e-2; + 2.33520497626869185e-3]; + + y = abs(x(k)); + z = 1 ./ (y .* y); + xnum = p(6).*z; + xden = z; + for i = 1:4 + xnum = (xnum + p(i)) .* z; + xden = (xden + q(i)) .* z; + end + result(k) = z .* (xnum + p(5)) ./ (xden + q(5)); + result(k) = (1/sqrt(pi) - result(k)) ./ y; + if jint ~= 2 + z = fix(y*16)/16; + del = (y-z).*(y+z); + result(k) = exp(-z.*z) .* exp(-del) .* result(k); + k = find(~isfinite(result)); + result(k) = 0*k; + end +end + result(k) = 0; + end +% +% fix up for negative argument, erf, etc. +% + if jint == 0 + k = find(x > xbreak); + result(k) = (0.5 - result(k)) + 0.5; + k = find(x < -xbreak); + result(k) = (-0.5 + result(k)) - 0.5; + elseif jint == 1 + k = find(x < -xbreak); + result(k) = 2. - result(k); + else % jint must = 2 + k = find(x < -xbreak); + z = fix(x(k)*16)/16; + del = (x(k)-z).*(x(k)+z); + y = exp(z.*z) .* exp(del); + result(k) = (y+y) - result(k); + end + + diff --git a/SD-VBS/common/toolbox/toolbox_basic/filter_hist/true_loc.m b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/true_loc.m new file mode 100755 index 0000000..7bf060f --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/true_loc.m @@ -0,0 +1,23 @@ +function a = true_loc(loca,g,scale); + +if ~exist('scale'), + scale = 50; +end + +y = loca(1,:); +x = loca(2,:); + +min_x = min(x); +min_y = min(y); + +x = x - min_x; +y = y - min_y; + +max_x = max(x);max_y = max(y); +min_scale = min(max_x,max_y); + +a(1) = (g(1)-1)*min_scale/(scale); +a(2) = (g(2)-1)*min_scale/(scale); + +a(1) = a(1) + min_x; +a(2) = a(2) + min_y; diff --git a/SD-VBS/common/toolbox/toolbox_basic/filter_hist/vmquant.m b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/vmquant.m new file mode 100755 index 0000000..ab4eb28 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/vmquant.m @@ -0,0 +1,112 @@ +function [im, map] = vmquant(arg1,arg2,arg3,arg4,arg5,arg6,arg7) +%VMQUANT Variance Minimization Color Quantization. +% [X, MAP] = VMQUANT(R,G,B,K,[Qr Qg Qb],DITHER,Qe) or +% VMQUANT(RGB,K,[Qr Qg Qb],DITHER,Qe), where RGB is a 3-D array, +% converts an arbitrary image comprised of RGB triples into an +% indexed image X with color map MAP. K specifies the number +% of desired entries in the target color map, and [Qr Qg Qb] +% specifies the number of quantization bits to assign each color +% axis during color interpolation. DITHER is a string ('dither' or +% 'nodither') that indicates whether or not to perform error propagation +% dither on the output image. Qe specifies the number of bits of +% quantization used in the error calculations. +% +% K is optional and defaults to 256. +% [Qr Qg Qb] is optional and defaults to [5 5 5]. +% DITHER is optional and defaults to 'nodither'. +% Qe is optional and defaults to 8. +% +% See also: RGB2IND, RGB2GRAY, DITHER, IND2RGB, CMUNIQUE, IMAPPROX. + +% This is the wrapper function for the MEX file VMQUANTC.C + +% Joseph M. Winograd 6-93 +% Copyright (c) 1993 by The MathWorks, Inc. +% $Revision: 5.3 $ $Date: 1996/08/22 22:09:03 $ + +% Reference: Xiaolin Wu, "Efficient Statistical Computation for +% Optimal Color Quantization," Graphics Gems II, (ed. James +% Arvo). Academic Press: Boston. 1991. + +if nargin < 1, + error('Not enough input arguments.'); +end + +threeD = (ndims(arg1)==3); % Determine if input includes a 3-D array + +if threeD, + error( nargchk( 1, 5, nargin ) ); + + % NOTE: If you change defaults, change them also + % in VMQUANTC.C and recompile the MEX function. + if nargin < 5 + arg5 = 8; % DEFAULT_QE = 8 + end + + if nargin < 4 + arg4 = 'n'; % DEFAULT_DITHER = 0 + end + + if nargin < 3 + arg3 = [5 5 5]; % DEFAULT_Q = [5 5 5] + end + + if nargin < 2 + arg2 = 256; % DEFAULT_K = 256 + end + + rout = arg1(:,:,1); + g = arg1(:,:,2); + b = arg1(:,:,3); + + if strcmp(lower(arg4(1)),'d') + dith = 1; + else + dith = 0; + end + + arg7 = arg5; + arg5 = arg3; + arg4 = arg2; + +else + error( nargchk( 3, 7, nargin ) ); + + if nargin < 7 + arg7 = 8; % DEFAULT_QE = 8 + end + + if nargin < 6 + arg6 = 'n'; % DEFAULT_DITHER = 0 + end + + if nargin < 5 + arg5 = [5 5 5]; % DEFAULT_Q = [5 5 5] + end + + if nargin < 4 + arg4 = 256; % DEFAULT_K = 256 + end + + rout = arg1; + g = arg2; + b = arg3; + + if strcmp(lower(arg6(1)),'d') + dith = 1; + else + dith = 0; + end + +end + +if (~isa(rout,'uint8')) + rout = uint8(round(255*rout)); +end +if (~isa(g,'uint8')) + g = uint8(round(255*g)); +end +if (~isa(b,'uint8')) + b = uint8(round(255*b)); +end +[im,map] = vmquantc( rout, g, b, arg4, arg5, dith, arg7 ); diff --git a/SD-VBS/common/toolbox/toolbox_basic/filter_hist/wismm.m b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/wismm.m new file mode 100755 index 0000000..915e07d --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/wismm.m @@ -0,0 +1,26 @@ +function [L1,L2,phi,Txx,Txy,Tyy]=wismm(X,N); +% [L1,L2,phi,T11,T12,T22]=wismm(X,N); +% Calculate windowed image second moment matrices for image X and return +% the following values: +% +% L1 is the larger eigenvalue (lambda_1) +% L2 is the smaller eigenvalue (lambda_2) +% phi is the angle of the 1st eigenvector (phi) + +[G1,G2]=gradient(X); + +GGTxx=G1.^2; +GGTxy=G1.*G2; +GGTyy=G2.^2; + +Txx=gaussN(GGTxx,N); +Txy=gaussN(GGTxy,N); +Tyy=gaussN(GGTyy,N); + +tr=Txx+Tyy; +V1=0.5*sqrt(tr.^2-4*(Txx.*Tyy-Txy.^2)); + +L1=real(0.5*tr+V1); +L2=real(0.5*tr-V1); +phi=0.5*atan2(2*Txy,Txx-Tyy); + diff --git a/SD-VBS/common/toolbox/toolbox_basic/filter_hist/wismm2.m b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/wismm2.m new file mode 100755 index 0000000..ae62ce9 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/wismm2.m @@ -0,0 +1,66 @@ +function [L1,L2,phi,aniso,pol,con,window_sizes]=wismm2(V); +% [L1,L2,phi,aniso,pol,con,window_sizes]=wismm2(V); +% Calculate windowed image second moment matrices for image V and return +% the following values: +% +% L1 is the larger eigenvalue (lambda_1) +% L2 is the smaller eigenvalue (lambda_2) +% phi is the angle of the 1st eigenvector (phi) +% + +[Gx,Gy]=gradient(V); + +GGTxx=Gx.^2; +GGTxy=Gx.*Gy; +GGTyy=Gy.^2; + +[r,c]=size(V); + +min_window_size=3; +max_window_size=3*round(min(r,c)/16); +if (-1)^max_window_size==1 + max_window_size=max_window_size+1; +end +window_step_size=2; + +window_sizes=min_window_size:2:max_window_size; +max_count=length(window_sizes); + +L1=zeros(r,c,max_count); +L2=zeros(r,c,max_count); +phi=zeros(r,c,max_count); +pol=zeros(r,c,max_count); +con=zeros(r,c,max_count); + +fprintf(1,'Integration window size: '); +counter=1; +for n=window_sizes + fprintf(1,'%d ',n); + Txx=gaussN(GGTxx,n); + Txy=gaussN(GGTxy,n); + Tyy=gaussN(GGTyy,n); + + tr=Txx+Tyy; + V1=0.5*sqrt(tr.^2-4*(Txx.*Tyy-Txy.^2)); + V1=real(V1); + + L1(:,:,counter)=0.5*tr+V1; + L2(:,:,counter)=0.5*tr-V1; + phi(:,:,counter)=0.5*atan2(2*Txy,Txx-Tyy); + + % do polarity stuff here + grad_smooth_x=gaussN(Gx,n); + grad_smooth_y=gaussN(Gy,n); + grad_smooth_mag=sqrt(grad_smooth_x.^2+grad_smooth_y.^2); + grad_mag=sqrt(Gx.^2+Gy.^2); + grad_mag_smooth=gaussN(grad_mag,n); + pol(:,:,counter)=grad_smooth_mag./(grad_mag_smooth+eps); + + % contrast calculation + con(:,:,counter)=tr; + counter=counter+1; +end +fprintf(1,'\n') + +aniso=1-L2./(L1+eps); + diff --git a/SD-VBS/common/toolbox/toolbox_basic/filter_hist/wismm3.m b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/wismm3.m new file mode 100755 index 0000000..89c56ef --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/wismm3.m @@ -0,0 +1,71 @@ +function [L1,L2,phi,aniso,pol,con,window_sizes]=wismm3(V); +% [L1,L2,phi,aniso,pol,con,window_sizes]=wismm3(V); +% Calculate windowed image second moment matrices for image V and return +% the following values: +% +% L1 is the larger eigenvalue (lambda_1) +% L2 is the smaller eigenvalue (lambda_2) +% phi is the angle of the 1st eigenvector (phi) +% + +[Gx,Gy]=gradient(V); + +GGTxx=Gx.^2; +GGTxy=Gx.*Gy; +GGTyy=Gy.^2; + +[r,c]=size(V); + +min_window_size=3; +max_window_size=3*round(min(r,c)/16); +if (-1)^max_window_size==1 + max_window_size=max_window_size+1; +end +window_step_size=2; + +window_sizes=min_window_size:2:max_window_size; +max_count=length(window_sizes); + +L1=zeros(r,c,max_count); +L2=zeros(r,c,max_count); +phi=zeros(r,c,max_count); +pol=zeros(r,c,max_count); +con=zeros(r,c,max_count); + +fprintf(1,'Integration window size: '); +counter=1; +for n=window_sizes + fprintf(1,'%d ',n); + Txx=gaussN(GGTxx,n); + Txy=gaussN(GGTxy,n); + Tyy=gaussN(GGTyy,n); + + tr=Txx+Tyy; + V1=0.5*sqrt(tr.^2-4*(Txx.*Tyy-Txy.^2)); + V1=real(V1); + + L1(:,:,counter)=0.5*tr+V1; + L2(:,:,counter)=0.5*tr-V1; + phi(:,:,counter)=0.5*atan2(2*Txy,Txx-Tyy); + + % do polarity stuff here + [P,angle_vector]=polarity(Gx,Gy,n); + quant_bound=angle_vector(2)/2; + % (quantize angle and pull corresponding polarity out of P) + % (perhaps use set-theoretic functions for masking out P???) + for m=1:length(angle_vector); + a=angle_vector(end-m+1); + old_pol=pol(:,:,counter); + Pmask=abs(cos(phi(:,:,counter)-a))>=cos(quant_bound); + Pmask=Pmask&(old_pol==0); % prevent pileup on quant. boundaries + pol(:,:,counter)=old_pol+(Pmask.*P(:,:,m)); + end + + % contrast calculation + con(:,:,counter)=tr; + counter=counter+1; +end +fprintf(1,'\n') + +aniso=1-L2./(L1+eps); + diff --git a/SD-VBS/common/toolbox/toolbox_basic/filter_hist/write_command.m b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/write_command.m new file mode 100755 index 0000000..954a39e --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/write_command.m @@ -0,0 +1,8 @@ +function write_command(fname,fn_base,para) + +fid = fopen(fname,'w'); + +fprintf(fid,'%s ',fn_base); +fprintf(fid,'%d ',para); +fprintf(fid,'\nrun\n'); +fclose(fid); diff --git a/SD-VBS/common/toolbox/toolbox_basic/filter_hist/write_test.m b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/write_test.m new file mode 100755 index 0000000..e444c27 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/write_test.m @@ -0,0 +1,38 @@ + +I_max = 250; +tex_max = 30; + +%fnames = [130038,130039,130042,130056,130057]; +%fnames = [334074 334031 334044 334003 334065 334000 334039 334018 334002 334029] + +fnames = 130057; + +for j=1:length(fnames), +fname = sprintf('images/%d.pgm',fnames(j)); + +sigs = [1/sqrt(2),1,sqrt(2),2,2*sqrt(2)];r = 3;szs = round(r*3*sigs); +szs = szs(length(szs))*ones(1,length(szs)); +num_ori = 6; + +I = readpgm(fname); +[text_des,filters] = compute_filter_fft(I,sigs,r,szs,num_ori); + +outname = sprintf('plaatje_data/%d',fnames(j)); + +cutsz =20; +I = cutoff(I,cutsz);%figure(1);im(I); +text_des = cutoff(text_des,cutsz); + +writeout_feature(I,text_des(:,:,:),outname,I_max,tex_max); + + +if 0, +for j=0:30, + cm = sprintf('!mv plaatje_data/134013.pfm_%d.pfm plaatje_data/134013_%d.pfm',j,j); + disp(cm);eval(cm); +end +end + +end + +exit diff --git a/SD-VBS/common/toolbox/toolbox_basic/filter_hist/writeout_feature.m b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/writeout_feature.m new file mode 100755 index 0000000..5376d5f --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/writeout_feature.m @@ -0,0 +1,40 @@ +function writeout_feature(I,tex,fname,I_max,tex_max) +% +% writeout_feature(I,tex,fname,I_max,tex_max) +% +% + + +%%%%% print out image +I_min = min(I(:)); + +I = I-I_min; +I = min(1,I/(I_max-I_min)); + +I = 2*I-1; + +j = 0; +fn = sprintf('%s_%d.pfm',fname,j); +cm = sprintf('writepfm: I->%s',fn); +disp(cm); +writepfm(fn,I); + + +%%% print out texture +nf = size(tex,3) + +for j=1:nf, + + fn = sprintf('%s_%d.pfm',fname,j); + cm = sprintf('writepfm:tex_%d->%s',j,fn); + disp(cm); + +tex(:,:,j) = tex(:,:,j)/tex_max;fprintf('.'); +tex(:,:,j) = tex(:,:,j).*(tex(:,:,j)<=1) + 1*(tex(:,:,j)>1);fprintf('.') +tex(:,:,j) = tex(:,:,j).*(tex(:,:,j)>=-1) + (-1)*(tex(:,:,j)<-1);fprintf('.'); + + writepfm(fn,tex(:,:,j)); + + +end + diff --git a/SD-VBS/common/toolbox/toolbox_basic/filter_hist/writepfm.m b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/writepfm.m new file mode 100755 index 0000000..a831970 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/writepfm.m @@ -0,0 +1,11 @@ +function writepfm(name,I) +% +% writepfm(name,I) +% + [nr,nc] = size(I); + + fid = fopen(name, 'w'); + fprintf(fid, '%d %d\n', nr,nc); + fprintf(fid,'%f ',I); + fclose(fid); + diff --git a/SD-VBS/common/toolbox/toolbox_basic/filter_hist/writepgm.m b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/writepgm.m new file mode 100755 index 0000000..113cb18 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/writepgm.m @@ -0,0 +1,8 @@ +function I = writepgm(name,I) + + [y,x] = size(I); + + fid = fopen(name, 'w'); + fprintf(fid, 'P5\n%d %d\n255\n', x,y); + fwrite(fid, I', 'uint8'); + fclose(fid); diff --git a/SD-VBS/common/toolbox/toolbox_basic/filter_hist/writepmm.m b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/writepmm.m new file mode 100755 index 0000000..675df93 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/writepmm.m @@ -0,0 +1,14 @@ +function writepmm(name,I) +% +% writepmm(name,I) +% + + [nr,nc,nb] = size(I); + + fid = fopen(name,'w'); + + fprintf(fid, 'P5\n%d %d %d\n255\n', nc,nr,nb); + + fprintf(fid,'%f ',I); + fclose(fid); + diff --git a/SD-VBS/common/toolbox/toolbox_basic/filter_hist/writepnm5.m b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/writepnm5.m new file mode 100755 index 0000000..633fba9 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/filter_hist/writepnm5.m @@ -0,0 +1,26 @@ +function writepnm5(name,I) +% +% writepnm5(name,I) +% +% I is a mul-band image +% + + [nr,nc,nb] = size(I); + + fid = fopen(name,'w'); + + fprintf(fid, 'P5\n%d %d %d\n255\n', nc,nr,nb); + + n = nr*nc; + + J = []; + + for j=1:nb, + J = [J,reshape(I(:,:,j)',n,1)]; + end + + J = reshape(J',nb*n,1); + + fprintf(fid,'%f ',J); + fclose(fid); + diff --git a/SD-VBS/common/toolbox/toolbox_basic/filtersQuad/doog1.m b/SD-VBS/common/toolbox/toolbox_basic/filtersQuad/doog1.m new file mode 100755 index 0000000..dd8e87b --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/filtersQuad/doog1.m @@ -0,0 +1,32 @@ +function H=doog1(sig,r,th,N); +% H=doog1(sig,r,th,N); + + +% by Serge Belongie + +no_pts=N; % no. of points in x,y grid + +[x,y]=meshgrid(-(N/2)+1/2:(N/2)-1/2,-(N/2)+1/2:(N/2)-1/2); + +phi=pi*th/180; +sigy=sig; +sigx=r*sig; +R=[cos(phi) -sin(phi); sin(phi) cos(phi)]; +C=R*diag([sigx,sigy])*R'; + +X=[x(:) y(:)]; + +Gb=gaussian(X,[0 0]',C); +Gb=reshape(Gb,N,N); + +m=R*[0 sig]'; + +a=1; +b=-1; + +% make odd-symmetric filter +Ga=gaussian(X,m/2,C); +Ga=reshape(Ga,N,N); +Gb=rot90(Ga,2); +H=a*Ga+b*Gb; + diff --git a/SD-VBS/common/toolbox/toolbox_basic/filtersQuad/doog2.m b/SD-VBS/common/toolbox/toolbox_basic/filtersQuad/doog2.m new file mode 100755 index 0000000..a0511cb --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/filtersQuad/doog2.m @@ -0,0 +1,38 @@ +function G=doog2(sig,r,th,N); +% G=doog2(sig,r,th,N); +% Make difference of offset gaussians kernel +% theta is in degrees +% (see Malik & Perona, J. Opt. Soc. Amer., 1990) +% +% Example: +% >> imagesc(doog2(1,12,0,64,1)) +% >> colormap(gray) + +% by Serge Belongie + +no_pts=N; % no. of points in x,y grid + +[x,y]=meshgrid(-(N/2)+1/2:(N/2)-1/2,-(N/2)+1/2:(N/2)-1/2); + +phi=pi*th/180; +sigy=sig; +sigx=r*sig; +R=[cos(phi) -sin(phi); sin(phi) cos(phi)]; +C=R*diag([sigx,sigy])*R'; + +X=[x(:) y(:)]; + +Gb=gaussian(X,[0 0]',C); +Gb=reshape(Gb,N,N); + +m=R*[0 sig]'; +Ga=gaussian(X,m,C); +Ga=reshape(Ga,N,N); +Gc=rot90(Ga,2); + +a=-1; +b=2; +c=-1; + +G = a*Ga + b*Gb + c*Gc; + diff --git a/SD-VBS/common/toolbox/toolbox_basic/filtersQuad/make_filterbank_even2.m b/SD-VBS/common/toolbox/toolbox_basic/filtersQuad/make_filterbank_even2.m new file mode 100755 index 0000000..f7f4527 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/filtersQuad/make_filterbank_even2.m @@ -0,0 +1,45 @@ +function FB = make_filterbank(num_ori,filter_scales,wsz,enlong) +% +% F = make_filterbank(num_ori,num_scale,wsz) +% + +if nargin<4, + enlong = 3; +end + +enlong = 2*enlong; + +% definine filterbank +%num_ori=6; +%num_scale=3; + +num_scale = length(filter_scales); + +M1=wsz; % size in pixels +M2=M1; + +ori_incr=180/num_ori; +ori_offset=ori_incr/2; % helps with equalizing quantiz. error across filter set + +FB=zeros(M1,M2,num_ori,num_scale); + +% elongated filter set +counter = 1; + +for m=1:num_scale + for n=1:num_ori + % r=12 here is equivalent to Malik's r=3; + f=doog2(filter_scales(m),enlong,ori_offset+(n-1)*ori_incr,M1); + FB(:,:,n,m)=f; + end +end + +FB=reshape(FB,M1,M2,num_scale*num_ori); +total_num_filt=size(FB,3); + +for j=1:total_num_filt, + F = FB(:,:,j); + a = sum(sum(abs(F))); + FB(:,:,j) = FB(:,:,j)/a; +end + diff --git a/SD-VBS/common/toolbox/toolbox_basic/filtersQuad/make_filterbank_odd2.m b/SD-VBS/common/toolbox/toolbox_basic/filtersQuad/make_filterbank_odd2.m new file mode 100755 index 0000000..0059dca --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/filtersQuad/make_filterbank_odd2.m @@ -0,0 +1,46 @@ +function FB = make_filterbank(num_ori,filter_scales,wsz,enlong) +% +% F = make_filterbank(num_ori,num_scale,wsz) +% + +if nargin<4, + enlong = 3; +end + +enlong = enlong*2; + +% definine filterbank +%num_ori=6; +%num_scale=3; + +num_scale = length(filter_scales); + +M1=wsz; % size in pixels +M2=M1; + +ori_incr=180/num_ori; +ori_offset=ori_incr/2; % helps with equalizing quantiz. error across filter set + +FB=zeros(M1,M2,num_ori,num_scale); + + +% elongated filter set +counter = 1; + +for m=1:num_scale + for n=1:num_ori + % r=12 here is equivalent to Malik's r=3; + f=doog1(filter_scales(m),enlong,ori_offset+(n-1)*ori_incr,M1); + FB(:,:,n,m)=f; + end +end + +FB=reshape(FB,M1,M2,num_scale*num_ori); +total_num_filt=size(FB,3); + +for j=1:total_num_filt, + F = FB(:,:,j); + a = sum(sum(abs(F))); + FB(:,:,j) = FB(:,:,j)/a; +end + diff --git a/SD-VBS/common/toolbox/toolbox_basic/filtersQuad/quadedgep2.m b/SD-VBS/common/toolbox/toolbox_basic/filtersQuad/quadedgep2.m new file mode 100755 index 0000000..5041377 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/filtersQuad/quadedgep2.m @@ -0,0 +1,188 @@ +% function [xs,ys,gx,gy,par,threshold,mag,mage,g,FIe,FIo,mago] = quadedgep(I,par,threshold); +% Input: +% I = image +% par = vector for 4 parameters +% [number of filter orientations, number of scale, filter size, elongation] +% To use default values, put 0. +% threshold = threshold on edge strength +% Output: +% [x,y,gx,gy] = locations and gradients of an ordered list of edgels +% x,y could be horizontal or vertical or 45 between pixel sites +% but it is guaranteed that there [floor(y) + (floor(x)-1)*nr] +% is ordered and unique. In other words, each edgel has a unique pixel id. +% par = actual par used +% threshold = actual threshold used +% mag = edge magnitude +% mage = phase map +% g = gradient map at each pixel +% [FIe,FIo] = odd and even filter outputs +% mago = odd filter output of optimum orientation + +% Stella X. Yu, 2001 + +% This is the multi scale version of the filtering +% For the moment the parameters are defined by default. See line 34 + + +function [x,y,gx,gy,par,threshold,mag_s,mage,g,FIe,FIo,mago] = quadedgep2(I,par,data,threshold); + + +if nargin<4 | isempty(threshold), + threshold = 0.1; +end + +[r,c] = size(I); +def_par = [4,30,3]; + +display_on = 1; + +% take care of parameters, any missing value is substituted by a default value +if nargin<2 | isempty(par), + par = def_par; +end +% par(end+1:4)=0; +% par = par(:); +% j = (par>0); +% have_value = [ j, 1-j ]; +% j = 1; n_filter = have_value(j,:) * [par(j); def_par(j)]; +% j = 2; n_scale = have_value(j,:) * [par(j); def_par(j)]; +% j = 3; winsz = have_value(j,:) * [par(j); def_par(j)]; +% j = 4; enlong = have_value(j,:) * [par(j); def_par(j)]; + +n_ori = par(1); %if it doesn't work, par<-def_par + +winsz = par(2); +enlong = par(3); + +% always make filter size an odd number so that the results will not be skewed +j = winsz/2; +if not(j > fix(j) + 0.1), + winsz = winsz + 1; +end + +% filter the image with quadrature filters +if (isempty(data.W.scales)) + error ('no scales entered'); +end + +n_scale=length(data.W.scales); +filter_scales=data.W.scales; +% +% if strcmp(data.dataWpp.mode,'multiscale') +% n_scale=size((data.dataWpp.scales),2); +% filter_scales=data.dataWpp.scales; +% else +% filter_scales=data.dataWpp.scales(1); +% n_scale=1; +% end +% if n_scale>0&&strcmp(data.dataWpp.mode,'multiscale') +% if (~isempty(data.dataWpp.scales)) +% filter_scales=data.dataWpp.scales; +% else +% filter_scales=zeros(1,n_scale); +% +% for i=1:n_scale, +% filter_scales(i)=(sqrt(2))^(i-1); +% end +% data.dataWpp.scales=filter_scales; +% end +% else filter_scale=1; +% data.dataWpp.scales=filter_scales; +% end +% +% %%%%%%% juste pour que ca tourne +% if ~strcmp(data.dataWpp.mode,'multiscale') +% filter_scales=data.dataWpp.scales(1); +% n_scale=4; +% end +% %%%%%%%%%%%% + +FBo = make_filterbank_odd2(n_ori,filter_scales,winsz,enlong); +FBe = make_filterbank_even2(n_ori,filter_scales,winsz,enlong); +n = ceil(winsz/2); +f = [fliplr(I(:,2:n+1)), I, fliplr(I(:,c-n:c-1))]; +f = [flipud(f(2:n+1,:)); f; flipud(f(r-n:r-1,:))]; +FIo = fft_filt_2(f,FBo,1); +FIo = FIo(n+[1:r],n+[1:c],:); +FIe = fft_filt_2(f,FBe,1); +FIe = FIe(n+[1:r],n+[1:c],:); + +% compute the orientation energy and recover a smooth edge map +% pick up the maximum energy across scale and orientation +% even filter's output: as it is the second derivative, zero cross localize the edge +% odd filter's output: orientation + +[nr,nc,nb] = size(FIe); + +FIe = reshape(FIe, nr,nc,n_ori,length(filter_scales)); +FIo = reshape(FIo, nr,nc,n_ori,length(filter_scales)); + +mag_s = zeros(nr,nc,n_scale); +mag_a = zeros(nr,nc,n_ori); + +mage = zeros(nr,nc,n_scale); +mago = zeros(nr,nc,n_scale); +mage = zeros(nr,nc,n_scale); +mago = zeros(nr,nc,n_scale); + + + +for i = 1:n_scale, + mag_s(:,:,i) = sqrt(sum(FIo(:,:,:,i).^2,3)+sum(FIe(:,:,:,i).^2,3)); + mag_a = sqrt(FIo(:,:,:,i).^2+FIe(:,:,:,i).^2); + [tmp,max_id] = max(mag_a,[],3); + + base_size = nr * nc; + id = [1:base_size]'; + mage(:,:,i) = reshape(FIe(id+(max_id(:)-1)*base_size+(i-1)*base_size*n_ori),[nr,nc]); + mago(:,:,i) = reshape(FIo(id+(max_id(:)-1)*base_size+(i-1)*base_size*n_ori),[nr,nc]); + + mage(:,:,i) = (mage(:,:,i)>0) - (mage(:,:,i)<0); + + if display_on, + ori_incr=pi/n_ori; % to convert jshi's coords to conventional image xy + ori_offset=ori_incr/2; + theta = ori_offset+([1:n_ori]-1)*ori_incr; % orientation detectors + % [gx,gy] are image gradient in image xy coords, winner take all + + ori = theta(max_id); + ori = ori .* (mago(:,:,i)>0) + (ori + pi).*(mago(:,:,i)<0); + gy{i} = mag_s(:,:,i) .* cos(ori); + gx{i} = -mag_s(:,:,i) .* sin(ori); + g = cat(3,gx{i},gy{i}); + + % phase map: edges are where the phase changes + mag_th = max(max(mag_s(:,:,i))) * threshold; + eg = (mag_s(:,:,i)>mag_th); + h = eg & [(mage(2:r,:,i) ~= mage(1:r-1,:,i)); zeros(1,nc)]; + v = eg & [(mage(:,2:c,i) ~= mage(:,1:c-1,i)), zeros(nr,1)]; + [y{i},x{i}] = find(h | v); + k = y{i} + (x{i}-1) * nr; + h = h(k); + v = v(k); + y{i} = y{i} + h * 0.5; % i + x{i} = x{i} + v * 0.5; % j + t = h + v * nr; + gx{i} = g(k) + g(k+t); + k = k + (nr * nc); + gy{i} = g(k) + g(k+t); + +% figure(1); +% clf; +% imagesc(I);colormap(gray); +% hold on; +% quiver(x,y,gx,gy); hold off; +% title(sprintf('scale = %d, press return',i)); + + % pause; + 0; +else + x = []; + y = []; + gx = []; + gy =[]; + g= []; + end +end + + diff --git a/SD-VBS/common/toolbox/toolbox_basic/io/convert422.m b/SD-VBS/common/toolbox/toolbox_basic/io/convert422.m new file mode 100755 index 0000000..919e82e --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/io/convert422.m @@ -0,0 +1,27 @@ +image_current = '/hid/jshi'; + +image_dir = 'vr05_5 '; +pg_path = '/hid/jshi/422toppm/422toppm'; + +cm = sprintf('cd %s',image_dir); +disp(cm); +eval(cm); + +d = dir('seq*'); +filename = char(sort({d.name})); + +for j=1:size(filename), + cm = sprintf('!%s %s',pg_path,deblank(filename(j,:))); +disp(cm); +eval(cm); +end + + +%%% change back +cm = sprintf('cd %s',image_current); +disp(cm);eval(cm); + + +if 0, + deblank(filename(f,:)); +end diff --git a/SD-VBS/common/toolbox/toolbox_basic/io/im_vd.m b/SD-VBS/common/toolbox/toolbox_basic/io/im_vd.m new file mode 100755 index 0000000..590cd9b --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/io/im_vd.m @@ -0,0 +1,6 @@ +function J = im_vd(I); + +J(:,:,1) = I(1:2:end,1:2:end); +J(:,:,2) = I(2:2:end,1:2:end); + +montage2(J); diff --git a/SD-VBS/common/toolbox/toolbox_basic/io/imread2.m b/SD-VBS/common/toolbox/toolbox_basic/io/imread2.m new file mode 100755 index 0000000..27a5e4b --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/io/imread2.m @@ -0,0 +1,45 @@ +function I = imread2(fname,im_dir); +% +% I = imread2(fname,im_dir); +% + +cur_dir = pwd; + +if nargin>1, + cd(im_dir); +end + +%%% put on the necessary extension +d = dir(fname); + +if isempty(d), + d = dir([fname,'*']); +end + +if isempty(d), + I = []; +else + + fname = d.name; + + %%% find extension + k = findstr(fname,'.'); + ext = fname(k(end)+1:end); + + if (ext == 'bz2'), + cm = sprintf('!bzip2 -d %s',fname); + disp(cm);eval(cm); + I = imread2(fname(1:k(end-1)-1)); + cm = sprintf('!bzip2 %s',fname(1:k(end)-1)); + disp(cm);eval(cm); + elseif (ext == 'ppm'); + I = readppm(fname); + elseif (ext == 'pgm'); + I = readpgm(fname); + else + I = imread(fname); +I = double(I)/255; + end +end + +cd(cur_dir); diff --git a/SD-VBS/common/toolbox/toolbox_basic/io/peek_pgm_size.m b/SD-VBS/common/toolbox/toolbox_basic/io/peek_pgm_size.m new file mode 100755 index 0000000..13e54cd --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/io/peek_pgm_size.m @@ -0,0 +1,19 @@ +function [nr,nc] = peek_pgm_size(filename) +% function [nr,nc] = peek_pgm_size(filename) +% this is my version of pgmread for the pgm file created by XV. +% +% this program also corrects for the shifts in the image from pm file. + + +fid = fopen(filename,'r'); +fscanf(fid, 'P5\n'); +cmt = '#'; +while findstr(cmt, '#'), + cmt = fgets(fid); + if length(findstr(cmt, '#')) ~= 1, + YX = sscanf(cmt, '%d %d'); + nc = YX(1); nr = YX(2); + end +end + +fclose(fid); diff --git a/SD-VBS/common/toolbox/toolbox_basic/io/pgmread.m b/SD-VBS/common/toolbox/toolbox_basic/io/pgmread.m new file mode 100755 index 0000000..49a35a8 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/io/pgmread.m @@ -0,0 +1,24 @@ +function [img,header] = pgmread(filename) +% +% [img,header] = pgmread(filename) + +[fid, msg] = fopen(filename, 'r'); +if fid == -1, + error(msg) +end + +head = []; +good = 0; +while (good == 0) , + l = fgetl(fid); + if (length(l) == 3), + if (l == '255'), + good = 1; + sze = sscanf(header,'%d'); + end + end + header= l; +end + +img = fread(fid, sze', 'uchar')'; +fclose(fid); diff --git a/SD-VBS/common/toolbox/toolbox_basic/io/ppmtojpg.m b/SD-VBS/common/toolbox/toolbox_basic/io/ppmtojpg.m new file mode 100755 index 0000000..ce47e45 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/io/ppmtojpg.m @@ -0,0 +1,25 @@ +function []= ppm2jpg(fname,dlm,ori) +% +% ppm2jpg(fname,dlm,ori) +% +% dlm =1, remove the file extension from fname +% before convert +% ori =1, transpose the image +% + +if dlm, + dlm = findstr(fname,'.'); + fname = fname(1:dlm(end)-1); +end + +fname_1 = sprintf('%s.ppm',fname); +I = readppm(fname_1); + +if ori == 1, + I = permute(I,[2 1 3]); +end + + +fname_2 = sprintf('%s.jpg',fname); +imwrite(I,fname_2,'jpeg','Quality',90); + diff --git a/SD-VBS/common/toolbox/toolbox_basic/io/read422.m b/SD-VBS/common/toolbox/toolbox_basic/io/read422.m new file mode 100755 index 0000000..31a27f9 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/io/read422.m @@ -0,0 +1,45 @@ +function I = read422(fname,nc); +% +% I = read422(fname,width); +% +% read in a .422 file, need to pass image width, default = 640 +% + +% assume image width = 640 +if nargin<2, + nc = 640; +end + +%% find the image size +fid = fopen(fname); +fseek(fid,0,1); +fsize = ftell(fid); + +nr = fsize/nc/2; +fseek(fid,0,-1); + +%% read in Ybr data +data = fread(fid,fsize,'uchar'); + +%%% extract Y, Cb, Cr +Y1 = data(1:2:end); Y1 = reshape(Y1,nc,nr)'; +Cb1 = data(2:4:end); Cb1 = reshape(Cb1,nc/2,nr)'; +Cr1 = data(4:4:end); Cr1 = reshape(Cr1,nc/2,nr)'; + +Cb = zeros(size(Y1)); +Cr = zeros(size(Y1)); + +Cb(:,1:2:end) = Cb1; Cb(:,2:2:end) = Cb1; +%Cb(:,2:2:end) = 0.5*(Cb1+[Cb1(:,2:end),Cb1(:,end)]); + +Cr(:,1:2:end) = Cr1; Cr(:,2:2:end) = Cr1; +%Cr(:,2:2:end) = 0.5*(Cr1+[Cr1(:,2:end),Cr1(:,end)]); + +%%% convert to r,g,b +r = 1.164*(Y1-16.0) + 1.596*(Cr-128.0); +g = 1.164*(Y1-16.0) - 0.813*(Cr-128.0) - 0.391*(Cb-128.0); +b = 1.164*(Y1-16.0) + 2.018*(Cb-128.0); + +I = cat(3,r,g,b); +I = max(0,min(I,255)); +I = I/255; diff --git a/SD-VBS/common/toolbox/toolbox_basic/io/read422f.m b/SD-VBS/common/toolbox/toolbox_basic/io/read422f.m new file mode 100755 index 0000000..0063000 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/io/read422f.m @@ -0,0 +1,50 @@ +function I = read422(fname,nc); +% +% I = read422(fname,width); +% +% read in a .422 file, need to pass image width, default = 640 +% + +% assume image width = 640 +if nargin<2, + nc = 640; +end + +%% find the image size +fid = fopen(fname); +fseek(fid,0,1); +fsize = ftell(fid); + +nr = fsize/nc/2; + +fseek(fid,0,-1); + +%% read in Ybr data +data = fread(fid,fsize,'uchar'); + +%%% extract Y, Cb, Cr +Y1 = data(1:2:end); Y1 = reshape(Y1,nc,nr)'; +Cb1 = data(2:4:end); Cb1 = reshape(Cb1,nc/2,nr)'; +Cr1 = data(4:4:end); Cr1 = reshape(Cr1,nc/2,nr)'; + +Cb = zeros(size(Y1)); +Cr = zeros(size(Y1)); + +Cb(:,1:2:end) = Cb1; Cb(:,2:2:end) = Cb1; +%Cb(:,2:2:end) = 0.5*(Cb1+[Cb1(:,2:end),Cb1(:,end)]); + +Cr(:,1:2:end) = Cr1; Cr(:,2:2:end) = Cr1; +%Cr(:,2:2:end) = 0.5*(Cr1+[Cr1(:,2:end),Cr1(:,end)]); + +%%% convert to r,g,b +r = 1.164*(Y1-16.0) + 1.596*(Cr-128.0); +g = 1.164*(Y1-16.0) - 0.813*(Cr-128.0) - 0.391*(Cb-128.0); +b = 1.164*(Y1-16.0) + 2.018*(Cb-128.0); + +r = flipud(max(0,min(r,255))); +g = flipud(max(0,min(g,255))); +b = flipud(max(0,min(b,255))); + +I = cat(3,r,g,b); + +I = permute(I/255,[2,1,3]); diff --git a/SD-VBS/common/toolbox/toolbox_basic/io/read_cimgs.m b/SD-VBS/common/toolbox/toolbox_basic/io/read_cimgs.m new file mode 100755 index 0000000..d5df7f5 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/io/read_cimgs.m @@ -0,0 +1,40 @@ +function Is = read_imgs(homedir,imgdir,prename,postname,digits,startid,endid,step_img) +% +% Is = read_imgs(homedir,imgdir,prename,postname,digits,startid,endid,step_img) +% + + + +command = ['%s%s%s%.',num2str(digits),'d%s']; + +fname = sprintf(command,homedir,imgdir,prename,startid,postname); +disp(fname); +if (strcmp('.ppm',postname)), + I1 = readppm(fname); +else + I1 = imread(fname); +end + + +Is = zeros(size(I1,1),size(I1,2),size(I1,3),1+floor((endid-startid)/step_img)); +Is(:,:,:,1) = I1; +im_id = 1; +for j = startid+step_img:step_img:endid, + command = ['%s%s%s%.',num2str(digits),'d%s']; + fname = sprintf(command,homedir,imgdir,prename,j,postname); + disp(fname); + im_id = im_id+1; + + if (strcmp('.ppm',postname)), + Is(:,:,:,im_id) = readppm(fname); + else + a = imread(fname); + Is(:,:,:,im_id) = a; + end +end + + + + + + diff --git a/SD-VBS/common/toolbox/toolbox_basic/io/read_ev_pgm.m b/SD-VBS/common/toolbox/toolbox_basic/io/read_ev_pgm.m new file mode 100755 index 0000000..3f7b69d --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/io/read_ev_pgm.m @@ -0,0 +1,26 @@ +function [evs,ev_info] = read_ev_pgm(basename,start_id,end_id,neigs) +% +% evs = read_ev_pgm(basename,start_id,end_id,neigs) +% +% + +fname = sprintf('%s_ev_%.2d.%.2d.pgm',basename,start_id,1) +[nr,nc] = peek_pgm_size(fname); + +evs = zeros(nr,nc,neigs-1,start_id-end_id+1); +ev_info = zeros(4,neigs-1,start_id-end_id+1); + +for j=start_id:end_id, + for k=1:neigs-1, + + fname = sprintf('%s_ev_%.2d.%.2d.pgm',basename,j,k); + [I,info] = readpgm_evinfo(fname); + + if (length(info)<4) + info = [0;0;0;0]; + end + + evs(:,:,k,j-start_id+1) = I; + ev_info(:,k,j-start_id+1) = info'; + end +end diff --git a/SD-VBS/common/toolbox/toolbox_basic/io/read_ev_pgm2.m b/SD-VBS/common/toolbox/toolbox_basic/io/read_ev_pgm2.m new file mode 100755 index 0000000..b0cc3f9 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/io/read_ev_pgm2.m @@ -0,0 +1,29 @@ +function [evs,ev_info] = read_ev_pgm2(basename,start_id,end_id,neigs) +% +% evs = read_ev_pgm(basename,start_id,end_id,neigs) +% +% read_ev_pgm.m modified by SXY in Feb. 2001. +% The first eigenvector is also included + +fname = sprintf('%s_ev_%.2d.%.2d.pgm',basename,start_id,1) +[nr,nc] = peek_pgm_size(fname); + +evs = zeros(nr,nc,neigs,start_id-end_id+1); +ev_info = zeros(4,neigs,start_id-end_id+1); + +for j=start_id:end_id, + + for k=1:neigs, + + fname = sprintf('%s_ev_%.2d.%.2d.pgm',basename,j,k-1); + + [I,info] = readpgm_evinfo(fname); + + if (length(info)<4) + info = [0;0;0;0]; + end + + evs(:,:,k,j-start_id+1) = I; + ev_info(:,k,j-start_id+1) = info'; + end +end diff --git a/SD-VBS/common/toolbox/toolbox_basic/io/read_ev_pgm_real.m b/SD-VBS/common/toolbox/toolbox_basic/io/read_ev_pgm_real.m new file mode 100755 index 0000000..d985679 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/io/read_ev_pgm_real.m @@ -0,0 +1,30 @@ +function [evs,ev_info] = read_ev_pgm(basename,start_id,end_id,neigs) +% +% evs = read_ev_pgm(basename,start_id,end_id,neigs) +% +% + +fname = sprintf('%s_ev_%.2d.%.2d.pgm',basename,start_id,1); +[nr,nc] = peek_pgm_size(fname); + +evs = zeros(nr,nc,neigs-1,start_id-end_id+1); +ev_info = zeros(4,neigs-1,start_id-end_id+1); + +for j=start_id:end_id, + for k=1:neigs, + + fname = sprintf('%s_ev_%.2d.%.2d.pgm',basename,j,k-1); + [I,info] = readpgm_evinfo(fname); + + evs(:,:,k,j-start_id+1) = I; + ev_info(:,k,j-start_id+1) = info'; + end +end + +evs = squeeze(evs); + +for j=1:neigs, + evs(:,:,j) = (evs(:,:,j)/ev_info(3,j)) +ev_info(1,j); + %evs(:,:,j) = evs(:,:,j)/norm(reshape(evs(:,:,j),nr*nc,1)); +end + diff --git a/SD-VBS/common/toolbox/toolbox_basic/io/read_imgs.m b/SD-VBS/common/toolbox/toolbox_basic/io/read_imgs.m new file mode 100755 index 0000000..f84486c --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/io/read_imgs.m @@ -0,0 +1,47 @@ +function Is = read_imgs(homedir,imgdir,prename,postname,digits,startid,endid,step_img) +% +% Is = read_imgs(homedir,imgdir,prename,postname,digits,startid,endid,step_img) +% + + + +command = ['%s%s%s%.',num2str(digits),'d%s']; + +fname = sprintf(command,homedir,imgdir,prename,startid,postname); +disp(fname); +if (strcmp('.pgm',postname)), + I1 = readpgm(fname); +elseif (strcmp('.ppm',postname)) + a = readppm(fname); + I1 = sum(a,3); +else + a = imread(fname); a = sum(double(a),3); + I1 = a; +end + + +Is = zeros(size(I1,1),size(I1,2),1+floor((endid-startid)/step_img)); +Is(:,:,1) = I1; +im_id = 1; +for j = startid+step_img:step_img:endid, + command = ['%s%s%s%.',num2str(digits),'d%s']; + fname = sprintf(command,homedir,imgdir,prename,j,postname); + disp(fname); + im_id = im_id+1; + + if (strcmp('.pgm',postname)), + Is(:,:,im_id) = readpgm(fname); + elseif (strcmp('.ppm',postname)) + a = readppm(fname); + Is(:,:,im_id) = sum(a,3); + else + a = imread(fname); a = sum(double(a),3); + Is(:,:,im_id) = a; + end +end + + + + + + diff --git a/SD-VBS/common/toolbox/toolbox_basic/io/read_pmm.m b/SD-VBS/common/toolbox/toolbox_basic/io/read_pmm.m new file mode 100755 index 0000000..9e2eed1 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/io/read_pmm.m @@ -0,0 +1,12 @@ +function I = read_pmm(fname) + +fid = fopen(fname,'r'); + +[A] = fscanf(fid,'%d\n',3); + +I = fscanf(fid,'%d',prod(A)); + + +I = reshape(I,A(2),A(1))'; + +I = squeeze(I); diff --git a/SD-VBS/common/toolbox/toolbox_basic/io/read_scan.m b/SD-VBS/common/toolbox/toolbox_basic/io/read_scan.m new file mode 100755 index 0000000..6ad818a --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/io/read_scan.m @@ -0,0 +1,42 @@ +function [img,sizeinfo] = pgmread(filename) +% function img = pgmread(filename) +% this is my version of pgmread for the pgm file created by XV. +% +% this program also corrects for the shifts in the image from pm file. + + +fname_header = sprintf('%s.h01',filename); +fname_data = sprintf('%s.i01',filename); + +fid = fopen(fname_header,'r'); + + +done = 0; +while done~=3, + cmt = fgets(fid) + if (findstr(cmt,'!matrix size[1]')), + nc = sscanf(cmt,'!matrix size[1] :=%d'); + done = done+1; + elseif (findstr(cmt,'!matrix size[2]')), + nr = sscanf(cmt,'!matrix size[2] :=%d'); + done = done+1; + elseif (findstr(cmt,'!matrix size[3]')), + ns = sscanf(cmt,'!matrix size[3] :=%d'); + done = done+1; + end +end +fclose(fid); + +fid = fopen(fname_data,'r'); + +%img = fscanf(fid,'%d',size); +%img = img'; + +img = fread(fid,nc*nr*ns,'uint8'); +img = reshape(img,nc,nr,ns); + +sizeinfo(1) = nr; +sizeinfo(2) = nc; +sizeinfo(3) = ns; + +fclose(fid); diff --git a/SD-VBS/common/toolbox/toolbox_basic/io/read_seg_file.m b/SD-VBS/common/toolbox/toolbox_basic/io/read_seg_file.m new file mode 100755 index 0000000..a056ebc --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/io/read_seg_file.m @@ -0,0 +1,36 @@ +function [seg_map,seg] = read_seg(filename) +% +% function seg = read_seg(filename) +% + +fid = fopen(filename,'r'); +if (fid < 0), + error(sprintf('can not find file: %s',filename)); +end + +header_done =0; +while ~header_done, + + cmt = fgets(fid); + if length(findstr(cmt,'#')) ~=1, + header_done = 1; + cmt = fgets(fid); + nc = sscanf(cmt,'width %d\n'); + cmt = fgets(fid); + nr = sscanf(cmt,'height %d\n'); + cmt = fgets(fid); + mseg = sscanf(cmt,'segments %d\n'); + cmt = fgets(fid); + end +end + +seg = fscanf(fid,'%d',100*nr); +tmp = length(seg(:))/4; +seg = reshape(seg,4,tmp)'; + +seg_map = zeros(nr,nc); + +for j=1:tmp, + seg_map(seg(j,2)+1,1+seg(j,3):1+seg(j,4)) = seg(j,1); +end + diff --git a/SD-VBS/common/toolbox/toolbox_basic/io/readlines.m b/SD-VBS/common/toolbox/toolbox_basic/io/readlines.m new file mode 100755 index 0000000..90bc944 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/io/readlines.m @@ -0,0 +1,30 @@ +function [lines,indexes] = readlines(fname) +% +% [lines,indexes] = readlines(fname) +% Read Edges points from .Ins file produced by "getlines" +% lines: a num_pointsx2 matrix of the edge points +% indexes: the braking point the lines +% + +fid = fopen(fname,'r'); + +done = 0; +lines = []; +indexes = []; + +first_line = fscanf(fid,'%s',1); + +while (~done), + num_lines = sscanf(first_line(3:length(first_line)),'%d'); + disp(num_lines); + indexes = [indexes,num_lines]; + a = fscanf(fid,'%f',[2,num_lines]); + lines = [lines;a']; + + first_line = fscanf(fid,'%s',1); + if (first_line == []), + done = 1; + end +end + + diff --git a/SD-VBS/common/toolbox/toolbox_basic/io/readpdm3.m b/SD-VBS/common/toolbox/toolbox_basic/io/readpdm3.m new file mode 100755 index 0000000..c21fc48 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/io/readpdm3.m @@ -0,0 +1,16 @@ +function I = readpdm(filename) + +fid = fopen(filename,'r'); + +A = fscanf(fid,'%d',3) +A(3) = max(1,A(3)); + +I = fscanf(fid,'%d',[A(1)*A(2)*A(3)]); + +%I = fscanf(fid,'%f',A(2)*A(1));I = reshape(I,A(1),A(2)); + +I = reshape(I,A(2),A(1),A(3)); + +I = permute(I,[2,1,3]); + +fclose(fid); diff --git a/SD-VBS/common/toolbox/toolbox_basic/io/readpdmc.m b/SD-VBS/common/toolbox/toolbox_basic/io/readpdmc.m new file mode 100755 index 0000000..37910b9 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/io/readpdmc.m @@ -0,0 +1,12 @@ +function I = readpfm(filename) + +fid = fopen(filename,'r'); + +A = fscanf(fid,'%d',2); +I = fscanf(fid,'%d',[A(2),A(1)]); +%I = fscanf(fid,'%d',[300,1000]); +I = I'; + +%I = fscanf(fid,'%f',A(2)*A(1));I = reshape(I,A(1),A(2)); + +fclose(fid); diff --git a/SD-VBS/common/toolbox/toolbox_basic/io/readpfm.m b/SD-VBS/common/toolbox/toolbox_basic/io/readpfm.m new file mode 100755 index 0000000..48ecd78 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/io/readpfm.m @@ -0,0 +1,10 @@ +function I = readpfm(filename) + +fid = fopen(filename,'r'); + +A = fscanf(fid,'%d',2); +I = fscanf(fid,'%f',[A(1),A(2)]); + +%I = fscanf(fid,'%f',A(2)*A(1));I = reshape(I,A(1),A(2)); + +fclose(fid); diff --git a/SD-VBS/common/toolbox/toolbox_basic/io/readpfm3.m b/SD-VBS/common/toolbox/toolbox_basic/io/readpfm3.m new file mode 100755 index 0000000..15ba959 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/io/readpfm3.m @@ -0,0 +1,17 @@ +function I = readpfm(filename) + +fid = fopen(filename,'r'); + +A = fscanf(fid,'%d',3); +A(3) = max(1,A(3)); + +I = fscanf(fid,'%f',[A(1)*A(2)*A(3)]); + +%I = fscanf(fid,'%f',A(2)*A(1));I = reshape(I,A(1),A(2)); + +I = reshape(I,A(2),A(1),A(3)); +I = permute(I,[2,1,3]); + +I = squeeze(I); + +fclose(fid); diff --git a/SD-VBS/common/toolbox/toolbox_basic/io/readpfmc.m b/SD-VBS/common/toolbox/toolbox_basic/io/readpfmc.m new file mode 100755 index 0000000..2039002 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/io/readpfmc.m @@ -0,0 +1,11 @@ +function I = readpfm(filename) + +fid = fopen(filename,'r'); + +A = fscanf(fid,'%d',2); +I = fscanf(fid,'%f',[A(2),A(1)]); +I = I'; + +%I = fscanf(fid,'%f',A(2)*A(1));I = reshape(I,A(1),A(2)); + +fclose(fid); diff --git a/SD-VBS/common/toolbox/toolbox_basic/io/readpgm.m b/SD-VBS/common/toolbox/toolbox_basic/io/readpgm.m new file mode 100755 index 0000000..7aaf998 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/io/readpgm.m @@ -0,0 +1,30 @@ +function img = pgmread(filename) +% function img = pgmread(filename) +% this is my version of pgmread for the pgm file created by XV. +% +% this program also corrects for the shifts in the image from pm file. + + +fid = fopen(filename,'r'); +if (fid < 0), + error(sprintf('can not find file: %s',filename)); +end + +fscanf(fid, 'P5\n'); +cmt = '#'; +while findstr(cmt, '#'), + cmt = fgets(fid); + if length(findstr(cmt, '#')) ~= 1, + YX = sscanf(cmt, '%d %d'); + y = YX(1); x = YX(2); + end +end + +fgets(fid); + +%img = fscanf(fid,'%d',size); +%img = img'; + +img = fread(fid,[y,x],'uint8'); +img = img'; +fclose(fid); diff --git a/SD-VBS/common/toolbox/toolbox_basic/io/readpgm_evinfo.m b/SD-VBS/common/toolbox/toolbox_basic/io/readpgm_evinfo.m new file mode 100755 index 0000000..69f80ba --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/io/readpgm_evinfo.m @@ -0,0 +1,35 @@ +function [img,ev_info] = pgmread_evinfo(filename) +% function img = pgmread(filename) +% this is my version of pgmread for the pgm file created by XV. +% +% return the information in line # + + +fid = fopen(filename,'r'); + +if (fid <0), + error(sprintf('can not find file %s',filename)); +end + +fscanf(fid, 'P5\n'); +cmt = '#'; +while findstr(cmt, '#'), + cmt = fgets(fid); + if findstr(cmt,'#'), + ev_info = sscanf(cmt,'# minv: %f, maxv: %f, scale: %f, eigval: %f'); + end + if length(findstr(cmt, '#')) ~= 1, + YX = sscanf(cmt, '%d %d'); + y = YX(1); x = YX(2); + end +end + +fgets(fid); + +%img = fscanf(fid,'%d',size); +%img = img'; + +img = fread(fid,[y,x],'uint8'); +img = img'; +fclose(fid); + diff --git a/SD-VBS/common/toolbox/toolbox_basic/io/readpmm.m b/SD-VBS/common/toolbox/toolbox_basic/io/readpmm.m new file mode 100755 index 0000000..88fe907 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/io/readpmm.m @@ -0,0 +1,22 @@ +function I=readpmm(name) +% +% I=writepmm(name) +% +% I is a mul-band image +% + fid = fopen(name,'r'); + + if (fid <0), + error(sprintf('can not find file %s',name)); + end + + a = fscanf(fid,'%d',3); + nr = a(1);nc = a(2);nb = a(3); + + + I = fscanf(fid, '%f\n', nr*nc*nb); + + I = reshape(I,nc,nr,nb)'; + I = squeeze(I); + + fclose(fid); diff --git a/SD-VBS/common/toolbox/toolbox_basic/io/readppm.m b/SD-VBS/common/toolbox/toolbox_basic/io/readppm.m new file mode 100755 index 0000000..b9dd566 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/io/readppm.m @@ -0,0 +1,23 @@ +function [I,r, g, b] = readppm(name) + + fid = fopen(name, 'r'); + fscanf(fid, 'P6\n'); + cmt = '#'; + while findstr(cmt, '#'), + cmt = fgets(fid); + if length(findstr(cmt, '#')) ~= 1 + YX = sscanf(cmt, '%d %d'); + y = YX(1); x = YX(2); + end + end + fgets(fid); + packed = fread(fid,[3*y,x],'uint8')'; + r = packed(:,1:3:3*y); + g = packed(:,2:3:3*y); + b = packed(:,3:3:3*y); + fclose(fid); + + I(:,:,1) = r; + I(:,:,2) = g; + I(:,:,3) = b; + I = I/255; diff --git a/SD-VBS/common/toolbox/toolbox_basic/io/writepgm.m b/SD-VBS/common/toolbox/toolbox_basic/io/writepgm.m new file mode 100755 index 0000000..113cb18 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/io/writepgm.m @@ -0,0 +1,8 @@ +function I = writepgm(name,I) + + [y,x] = size(I); + + fid = fopen(name, 'w'); + fprintf(fid, 'P5\n%d %d\n255\n', x,y); + fwrite(fid, I', 'uint8'); + fclose(fid); diff --git a/SD-VBS/common/toolbox/toolbox_basic/io/writeppm.m b/SD-VBS/common/toolbox/toolbox_basic/io/writeppm.m new file mode 100755 index 0000000..3d2fed1 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/io/writeppm.m @@ -0,0 +1,14 @@ +function writeppm(name,I) + + [y,x,nb] = size(I); + + fid = fopen(name, 'w'); + fprintf(fid, 'P6\n%d %d\n255\n', x,y); + + I1 = reshape(I(:,:,1)',1,x*y); + I2 = reshape(I(:,:,2)',1,x*y); + I3 = reshape(I(:,:,3)',1,x*y); + + fwrite(fid, [I1;I2;I3], 'uint8'); + fclose(fid); + diff --git a/SD-VBS/common/toolbox/toolbox_basic/matching/pub/contrib/v5/optim/assignprob/Contents.m b/SD-VBS/common/toolbox/toolbox_basic/matching/pub/contrib/v5/optim/assignprob/Contents.m new file mode 100755 index 0000000..3ddb232 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/matching/pub/contrib/v5/optim/assignprob/Contents.m @@ -0,0 +1,26 @@ +%Functions related to the assignment problem. +%Version 1.0, 25-May-1999. +% +%Copyright (c) 1995-1999 Niclas Borlin, Dept. of Computing Science, +% Umea University, SE-901 87 UMEA, Sweden. +% Niclas.Borlin@cs.umu.se. +% www.cs.umu.se/~niclas. +% +%All standard disclaimers apply. +% +%You are free to use this code as you wish. If you use it for a +%publication or in a commercial package, please include an +%acknowledgement and/or at least send me an email. (Looks good in my CV :-). +% +%Main functions: +% hungarian - calculate a solution of the square assignment +% problem. See HELP for a reference. +% condass - calculate a condition number of the solution to the +% assignment problem. See HELP for a reference. +% allcosts - calculate the costs of all possible assignments. +% allperms - calculate all possible permutations/assignments of a +% given problem size. +% +%Test/demo functions. +% demo - short demonstration of the main functions. +% test - test/verification of the main functions. diff --git a/SD-VBS/common/toolbox/toolbox_basic/matching/pub/contrib/v5/optim/assignprob/allcosts.m b/SD-VBS/common/toolbox/toolbox_basic/matching/pub/contrib/v5/optim/assignprob/allcosts.m new file mode 100755 index 0000000..ffdb8b9 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/matching/pub/contrib/v5/optim/assignprob/allcosts.m @@ -0,0 +1,17 @@ +function [c,p]=allcosts(C) +%ALLCOSTS Calculate all costs for an assignment problem. +% +%[c,p]=allcosts(C) +%c returns the costs, p the corresponding permutations. + +% v1.0 95-07-18. Niclas Borlin, niclas@cs.umu.se. + +p=allperm(size(C,1)); + +c=zeros(size(p,1),1); + +I=eye(size(C,1)); + +for i=1:size(p,1) + c(i)=sum(C(logical(sparse(p(i,:),1:size(C,1),1)))); +end diff --git a/SD-VBS/common/toolbox/toolbox_basic/matching/pub/contrib/v5/optim/assignprob/allperm.m b/SD-VBS/common/toolbox/toolbox_basic/matching/pub/contrib/v5/optim/assignprob/allperm.m new file mode 100755 index 0000000..b8d419e --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/matching/pub/contrib/v5/optim/assignprob/allperm.m @@ -0,0 +1,17 @@ +function p=allperm(n) +%ALLPERM All permutation matrix. +% +%p=allperm(n) +%Returns a matrix with all permutations of 1:n stored row-wise. + +% v1.0 95-07-18. Niclas Borlin, niclas@cs.umu.se. + +if (n<=1) + p=1; +else + q=allperm(n-1); + p=[]; + for i=1:n + p=[p;i*ones(size(q,1),1) q+(q>=i)]; + end +end diff --git a/SD-VBS/common/toolbox/toolbox_basic/matching/pub/contrib/v5/optim/assignprob/condass.m b/SD-VBS/common/toolbox/toolbox_basic/matching/pub/contrib/v5/optim/assignprob/condass.m new file mode 100755 index 0000000..82552e7 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/matching/pub/contrib/v5/optim/assignprob/condass.m @@ -0,0 +1,54 @@ +function [k,C1,T1,C2,T2]=condass(A) +%CONDASS Calculate condition number of the assigment problem. +% +%[k,C1,T1,C2,T2]=condass(A) +%A - A square cost matrix. +%k - The condition number of the assigment problem. +%C1 - The best assigment. +%T1 - The lowest cost. +%C2 - The second best assignment. +%T2 - The second lowest cost. +% +%The condition number is calculated as the relative difference between +%the best and second best solutions, as described in Nystrom, Soderkvist, +%and Wedin, "A Note on some Identification Problems Arising in Roentgen +%Stereo Photogrammetric Analysis", J of Biomechanics, 27(10):1291-1294, +%1994. + +% v1.0 96-09-14. Niclas Borlin, niclas@cs.umu.se. + +% A substantial effort was put into this code. If you use it for a +% publication or otherwise, please include an acknowledgement and notify +% me by email. /Niclas + +% Create a large number used to block selected assignments. +big=sum(sum(A))+1; + +% Get best assigment. +[C1,T1]=hungarian(A); + +% Initialize second best solution. +T2=inf; +C2=zeros(size(C1)); + +% Create a work matrix. +B=A; +for i=1:length(C1) + % Block assigment in column i. + B(C1(i),i)=big; + % Get best assigment with this one blocked. + [C,T]=hungarian(B); + if (T=max).*(theta-pi) +... + ((theta>min)&(theta1) { + mexErrMsgTxt("Too many output arguments."); + } + if (!(mxIsSparse(in[0]))) { + mexErrMsgTxt("Input argument #1 must be of type sparse"); + } + if ( mxIsSparse(in[1]) || mxIsSparse(in[2]) ) { + mexErrMsgTxt("Input argument #2 & #3 must be of type full"); + } + + /* computation starts */ + m = mxGetM(in[0]); + n = mxGetN(in[0]); + pr = mxGetPr(in[0]); + pi = mxGetPi(in[0]); + pir = mxGetIr(in[0]); + pjc = mxGetJc(in[0]); + + i = mxGetM(in[1]); + j = mxGetN(in[1]); + xm = ((i>j)? i: j); + + i = mxGetM(in[2]); + j = mxGetN(in[2]); + yn = ((i>j)? i: j); + + if ( xm>0 && xm != m) { + mexErrMsgTxt("Row multiplication dimension mismatch."); + } + if ( yn>0 && yn != n) { + mexErrMsgTxt("Column multiplication dimension mismatch."); + } + + + nzmax = mxGetNzmax(in[0]); + cmplx = (pi==NULL ? 0 : 1); + out[0] = mxCreateSparse(m,n,nzmax,cmplx); + if (out[0]==NULL) { + mexErrMsgTxt("Not enough space for the output matrix."); + } + + qr = mxGetPr(out[0]); + qi = mxGetPi(out[0]); + qir = mxGetIr(out[0]); + qjc = mxGetJc(out[0]); + + /* left multiplication */ + x = mxGetPr(in[1]); + if (yn==0) { + for (j=0; j1); +end + +if nargin<5 | isempty(no_rep), + no_rep = 1; +end + +if visimg, + nr = nr * nc; +else + nv = nc; +end + +if nargin<6 | isempty(pixel_loc), + pixel_loc = 1:nr; +end + +% D^(1/2) +d = 1./(d(:)+eps); + +% first recover the first eigenvector +if no_rep, + u = (1/norm(d)) + zeros(nr,1); + s = [1;s(:)]; + nv = nv + 1; +else + u = []; +end + +% the full set of generalized eigenvectors +v = [u, reshape(v,[nr,nv-no_rep])]; + +% This is the real D, row sum +d = d.^2; + +% an equivalent way to compute v = diag(d) * v; +v = v .* d(:,ones(nv,1)); % to avoid using a big matrix diag(d) + +% synthesis +a = v(pixel_loc,:)*diag(s)*v'; diff --git a/SD-VBS/common/toolbox/toolbox_basic/stella/dispimg.m b/SD-VBS/common/toolbox/toolbox_basic/stella/dispimg.m new file mode 100755 index 0000000..4e419a0 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/stella/dispimg.m @@ -0,0 +1,65 @@ +% function dispimg(g,fmt,lgd,cmap) display multiple images in one figure. +% Input: +% g = a cell and fmt is a 1x2 vector specifying the layout. +% lgd = a string cell for the title of each image. +% cmap = the colormap (default is the gray, -1 for the inverted gray). +% ishori = a vector of 1/0 to display real and imag parts horizontally / vertically + +% Stella X. Yu, 2000. + +function dispimg(g,fmt,lgd,cmap,ishori); + +cellg = iscell(g); +if cellg, + num_fig = length(g); +else + num_fig = size(g,3); +end; + +if nargin<2 | isempty(fmt), + m = ceil(sqrt(num_fig)); + n = ceil(num_fig / m); +else + m = fmt(1); + n = fmt(2); +end + +if nargin<3 | isempty(lgd), + lgd = 1:num_fig; +end +if isnumeric(lgd), + lgd = cellstr(num2str(lgd(:),3)); +end +i = size(lgd); +if i(1)==1, + lgd = [lgd, cell(1,num_fig-i(2))]; +else + lgd = [lgd; cell(num_fig-i(1),1)]; +end + +if nargin<5 | isempty(ishori), + ishori = ones(num_fig,1); +end +ishori(end+1:num_fig) = ishori(end); + +for k=1:num_fig, + subplot(m,n,k); + if cellg, + showim(g{k},[],ishori(k)); + else + showim(g(:,:,k),[],ishori(k)); + end + title(lgd{k}); +end + +if nargin<4 | isempty(cmap), + cmap = gray; +end +if length(cmap)==1, + if cmap==1, + cmap = gray; + else + cmap = flipud(gray); + end +end +colormap(cmap); diff --git a/SD-VBS/common/toolbox/toolbox_basic/stella/firstncut.m b/SD-VBS/common/toolbox/toolbox_basic/stella/firstncut.m new file mode 100755 index 0000000..a22077d --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/stella/firstncut.m @@ -0,0 +1,67 @@ +% function [v,s,d] = firstncut(base_name,rec_num) +% Input: +% base_name = image name +% rec_num = parameter record number +% Output: +% v = eigenvectors +% s = eigenvalues +% d = normalization matrix d = 1/sqrt(rowsum(abs(a))) +% Convert Jianbo Shi's Ncut Ccode results from images to matlab matrices. + +% Stella X. Yu, 2000. + +function [v,s,d] = firstncut(base_name,rec_num); + +if nargin<2 | isempty(rec_num), + rec_num = 1; +end + +cur_dir = pwd; +globalenvar; +cd(IMAGE_DIR); +cd(base_name); + feval([base_name,'_par']); + j = length(p); + if rec_num>j, + disp(sprintf('parameter record number %d out of range %d, check %s!',rec_num,j,[base_name,'_par.m'])); + Qlabel = []; + v = []; + s = []; + ev_info = []; + return; + end + nv = p(rec_num).num_eigvecs; + no_rep = (p(rec_num).offset<1e-6); + + % read the image + cm=sprintf('I = readppm(''%s.ppm'');',base_name); + eval(cm); + + % read eigenvectors + base_name_hist = sprintf('%s_%d_IC',base_name,rec_num); + if no_rep, + [v,ev_info] = read_ev_pgm(base_name_hist,1,1,nv); + else + [v,ev_info] = read_ev_pgm2(base_name_hist,1,1,nv); + end + s = ev_info(4,:)'; + + % read the normalization matrix + d = readpfmc(sprintf('%s_%d_D_IC.pfm',base_name,rec_num)); +cd(cur_dir); + +% D^(1/2) +dd = (1./(d(:)+eps)); + +% recover real eigenvectors +for j = 1:nv-no_rep, + vmin = ev_info(1,j); + vmax = ev_info(2,j); + y = v(:,:,j).*((vmax - vmin)/256) + vmin; + %validity check: x = D^(1/2)y should be normalized + x = norm(y(:).*dd); + v(:,:,j) = y./x; +end + +dispimg(cat(3,mean(I,3),v),[],[{'image'};cellstr(num2str(s,3))]); + diff --git a/SD-VBS/common/toolbox/toolbox_basic/stella/getfnames.m b/SD-VBS/common/toolbox/toolbox_basic/stella/getfnames.m new file mode 100755 index 0000000..4990451 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/stella/getfnames.m @@ -0,0 +1,47 @@ +% function [fn,dn] = getfnames(direc,opt) +% Input: +% direc = directory +% opt = wildcat +% Output: +% fn = a cell with all filenames under direc and with opt +% dn = a cell with all directory names under direc and with opt +% For example, getfnames('19990910','*.jpg'); +% Set IS_PC according to your platform in globalenvar.m + +% Stella X. Yu, 2000. + +function [fn,dn] = getfnames(direc,opt) + +if (nargin<1 | isempty(direc)), + direc = '.'; +end + +if nargin<2 | isempty(opt), + opt = []; +end + +fn = {}; +dn = {}; + +cur_dir = pwd; +cd(direc); +s = dir(opt); +if isempty(s), + disp('getfnames: no data'); + return; +end + +n = length(s); +i = 1; +j = 1; +for k=1:n, + if s(k).isdir, + dn{j,1} = s(k).name; + j = j + 1; + else + fn{i,1} = s(k).name; + i = i + 1; + end +end + cd(cur_dir) +%[fn{1:n,1}]=deal(s.name); diff --git a/SD-VBS/common/toolbox/toolbox_basic/stella/getimage2.m b/SD-VBS/common/toolbox/toolbox_basic/stella/getimage2.m new file mode 100755 index 0000000..945ddd2 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/stella/getimage2.m @@ -0,0 +1,46 @@ +% function f = getimage2(imagefile) returns a normalized intensity image. +% If the file postfix is not given, then I will search any possible image file +% under the IMAGE_DIR. + +% Stella X. Yu, March 1999 + +function f = getimage2(imagefile) + +if exist(imagefile)==2, + g = {imagefile}; +else + g = {}; +end +globalenvar; +g = [g; getfnames(IMAGE_DIR,[imagefile,'.*'])]; + +j = 1; +for i=1:length(g), + k = findstr(g{i},'.'); + gp = g{i}(k(end)+1:end); + if strcmp(gp,'ppm'), + f = double(readppm(g{i})); + j = 0; + elseif sum(strcmp(gp,{'jpg','tif','jpeg','tiff','bmp','png','hdf','pcx','xwd'}))>0, + f = double(imread(g{i})); + j = 0; + end + if j==0, + disp(sprintf('This is an image read from %s under %s',g{i},IMAGE_DIR)); + break; + end +end +if j, + f = []; + disp('Image not found'); + return; +end + +if size(f,3)>1, + %f = sum(f,3)./3; + f = rgb2ntsc(f); + f = f(:,:,1); +end +minf = min(f(:)); +maxf = max(f(:)); +f = (f - minf) ./ (maxf - minf); diff --git a/SD-VBS/common/toolbox/toolbox_basic/stella/globalenvar.m b/SD-VBS/common/toolbox/toolbox_basic/stella/globalenvar.m new file mode 100755 index 0000000..1e61b61 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/stella/globalenvar.m @@ -0,0 +1,6 @@ +% globalenvar + +HOME_DIR = '/hid/jshi/Research/walking/stella'; +IMAGE_DIR = '/hid/jshi/test_images'; +C_DIR = '/hid/jshi/Research/Ncut_code_C'; +IS_PC = 0; diff --git a/SD-VBS/common/toolbox/toolbox_basic/stella/jshincut.m b/SD-VBS/common/toolbox/toolbox_basic/stella/jshincut.m new file mode 100755 index 0000000..d0f11cb --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/stella/jshincut.m @@ -0,0 +1,94 @@ +% function [par, rec_num] = jshincut(par,image_dir) +% Input: +% par = a structure with parameters for command_ncut.tex +% image_dir = the directory where the imagefile is stored +% Output: +% par = parameters used +% rec_num = record number in the NCut database +% Jianbo Shi's ncut_IC is applied to the image +% (If there is no .ppm format for the named image, +% conversion from related files would be attempted.) +% Results are organized according to the parameters. +% Example: jshincut('240018s'); +% See also: jshincutdefpar; ncutcheckin +% Set IS_PC according to your platform in globalenvar.m + +% Stella X. Yu, 2000. + +function [par,rec_num] = jshincut(par,image_dir) + +rec = jshincutdefpar; + +fields = fieldnames(rec); +nf = length(fields); + +if ischar(par), + imagename = par; + par = rec; + par.fname_base = imagename; +end + +globalenvar; + +if nargin<2 | isempty(image_dir), + image_dir = IMAGE_DIR; +end + +imagename = getfield(par,fields{1}); +for i=2:nf, + t = getfield(par,fields{i}); + if isempty(t), + par = setfield(par,fields{i},getfield(rec,fields{i})); + end +end + +% dir and filename +catchar = {'/','\'}; +catchar = catchar{IS_PC+1}; + +% first check if there is a ppm file for this image +if not(exist([image_dir,catchar,imagename,'.ppm'])), + j = getfnames(image_dir,[imagename,'.*']); + if isempty(j), + disp('Image not found.'); + return; + end + k = 0; + for i=1:length(j), + k = k + not(isempty(im2ppm(j{i},image_dir))); + if k==1, + disp(sprintf('%s -> %s.ppm succeeded.',j{i},imagename)); + break; + end + end + if k==0, + disp('Sorry. Attempt to convert your named image into ppm format failed.'); + return; + end +end + +cd(C_DIR); + +% generate command_ncut.tex file +fn = 'command_ncut.tex'; +fid = fopen(fn,'w'); +fprintf(fid,'%21s\t%s%c%s\n',fields{1},image_dir,catchar,imagename); +for i=2:nf, + t = getfield(par,fields{i}); + if isnumeric(t), + t = num2str(t); + end + fprintf(fid,['%21s\t%s\n'],fields{i},t); +end +fclose(fid); +%disp('You can check and modify command_ncut.tex before I run ncut_IC on it. Good?');pause(1); + +% run ncut_IC +unix(['.',catchar,'ncut_IC']); +cd(HOME_DIR); + +% check in +copyfile([C_DIR,catchar,fn],[image_dir,catchar,fn]); +rec_num = ncutcheckin(fn,image_dir,image_dir); +%delete([image_dir,catchar,imagename,'.ppm']); +%delete([image_dir,catchar,fn]); diff --git a/SD-VBS/common/toolbox/toolbox_basic/stella/jshincutdefpar.m b/SD-VBS/common/toolbox/toolbox_basic/stella/jshincutdefpar.m new file mode 100755 index 0000000..4f07192 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/stella/jshincutdefpar.m @@ -0,0 +1,20 @@ +% function rec = jshincutdefpar; +% default parameter setting for Jianbo Shi's NCut C codes + +% Stella X. Yu, 2000. + +function rec = jshincutdefpar; + +rec.fname_base = '240018s'; +rec.fname_ext = 'ppm'; +rec.num_eigvecs = 15; +rec.spatial_neighborhood_x=20; +rec.sigma_x= 10; +rec.sig_I= -0.16; +rec.sig_IC= 0.01; +rec.hr= 2; +rec.eig_blk_sze= 3; +rec.power_D= 1; +rec.offset = 0.0; +rec.sig_filter = 1.0; +rec.elong_filter = 3.0; diff --git a/SD-VBS/common/toolbox/toolbox_basic/stella/ncutcheckin.m b/SD-VBS/common/toolbox/toolbox_basic/stella/ncutcheckin.m new file mode 100755 index 0000000..cd82ee5 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/stella/ncutcheckin.m @@ -0,0 +1,136 @@ +% function rec_num = ncutcheckin(fn,sdir,tdir) +% Input: +% fn = parameter file name, default = 'command_ncut.tex' +% sdir = source dir for fn as well as data files +% tdir = target dir to check in, both default = IMAGE_DIR +% Output: +% rec_num = the number of current parameter records +% The imagefile_par.m is updated if fn contains a new +% parameter set. Data files are tagged and copied over to +% a subdir under tdir. +% Example: ncutcheckin; +% Set IS_PC, IMAGE_DIR according to your platform in globalenvar.m + +% Stella X. Yu, 2000. + +function rec_num = ncutcheckin(fn,sdir,tdir) + +globalenvar; + +cur_dir = pwd; + +if nargin<1 | isempty(fn), + fn = 'command_ncut.tex'; +end + +if nargin<2 | isempty(sdir), + sdir = IMAGE_DIR; +end + +if nargin<3 | isempty(tdir), + tdir = IMAGE_DIR; +end + +rec = jshincutdefpar; + +% first, generate a parameter record from fn +cd(sdir); +[names,values] = textread(fn,'%s %s','commentstyle','shell'); +n = length(names); +s = rec; +for i=1:n, + j = str2num(values{i}); + if isempty(j), + s = setfield(s,names{i},values{i}); + else + s = setfield(s,names{i},j); + end +end +cd(cur_dir); + +% special care to extract the image file name +imagename = getfield(s,names{1}); +catchar = {'/','\'}; +catchar = catchar{IS_PC + 1}; +k = max([0,findstr(imagename,catchar)]); +imagename = imagename(k+1:end); +s = setfield(s,names{1},imagename); + +% second, check if the target dir contains a profile for the image +cd(tdir); +if not(exist(imagename,'dir')), + mkdir(imagename); + cd(cur_dir); + j = [catchar,imagename,'.',getfield(s,names{2})]; + copyfile([sdir,j],[tdir,catchar,imagename,j]); + cd(tdir); +end +cd(imagename); +j = [imagename,'_par']; +if not(exist(j)), + rec_num = 1; + p = s; +else + % load par file + feval(j); + rec_num = length(p); + i = 1; + while (i<=rec_num), + k = 0; + for j=1:n, + k = k + sum(getfield(s,names{j})-getfield(p(i),names{j})); + end + if k==0, + if not(isempty(input(['Data already existed as record # ',num2str(i),... + '\nPress any non-return key to Overwrite'],'s'))), + break; + else + rec_num = i; % have checked in already, no update + cd(cur_dir); + return; + end + else + i = i + 1; + end + end + rec_num = i; % new parameter setting + p(rec_num)=s; +end +tdir = [tdir,catchar,imagename]; +cd(cur_dir); + +% third, check in data files +% leave .ppm and _edgecon, _phase files +% if not(exist([tdir,catchar,imagename,'.ppm'])), +% copyfile([sdir,catchar,imagename,'.ppm'],[tdir,catchar,imagename,'.ppm']); +% end + +% IC files only +dn = getfnames(sdir,[imagename,'*_IC*.*']); +header = sprintf('%s%c%s_%d_',tdir,catchar,imagename,rec_num); +j = length(imagename)+2; +k = length(dn); +for i=1:k, + copyfile([sdir,catchar,dn{i}],[header,dn{i}(j:end)]); + delete([sdir,catchar,dn{i}]); +end +disp(sprintf('%d files checked in as record #%d',k,rec_num)); + + +% finally, update parameter file +cd(tdir); +fid = fopen([imagename,'_par.m'],'w'); +fprintf(fid,'%% Last checked in at %s\n\n',datestr(now)); +for i=1:rec_num, + for j=1:n, + k = getfield(p(i),names{j}); + if ischar(k), + fprintf(fid,'p(%d).%s=\''%s\'';\n',i,names{j},k); + else + fprintf(fid,'p(%d).%s=%s;\n',i,names{j},num2str(k)); + end + end + fprintf(fid,'\n'); +end +fclose(fid); +cd(cur_dir); \ No newline at end of file diff --git a/SD-VBS/common/toolbox/toolbox_basic/stella/openfigure.m b/SD-VBS/common/toolbox/toolbox_basic/stella/openfigure.m new file mode 100755 index 0000000..e677014 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/stella/openfigure.m @@ -0,0 +1,52 @@ +% function openfigure(m,n,caption,isnew) +function h = openfigure(m,n,caption,isnew) + +if nargin<3, + caption = ' '; +end + +if nargin<4, + isnew = 1; +end + +if (m<=0 | n<=0) + return; +end + +if isnew, + h = figure; colormap(gray); +else + h = gcf; +end +clf + +subplot('position',[0,0,0.1,0.1]); axis off; +text(0.1,0.15,sprintf('S. X. Yu, %s',date),'FontSize',8); + +subplot('position',[0,0.96,0.1,0.1]); axis off; +text(0.1,0.15,caption,'FontSize',8); + +subplot(m,n,1); +%return + +if (m==1 & n==1), + return; +end + +%set(gcf,'PaperPosition',[0.25, 8, 8,2.5*m]); +% set(gcf,'PaperPosition',[0.25,0.25,8,10.5]); +%return + +if (m<=n), + set(gcf,'PaperOrientation','landscape','PaperPosition',[0.25,0.25,10.5,8]); +else + set(gcf,'PaperPosition',[0.25,0.25,8,10.5]); +end + +% comment on PaperPosition +% [a,b,c,d] +% (a,b) is the coordinate of the lower-left corner of the figure +% (a,b) = (0,0) is the lower-left corner of the paper +% (c,d) is the coordinate of the upper-right corner of the figure relative to the lower-left corner of the figure +% Therefore, c>=a, d>=b +% Full paper position would be [0,0,8.5,11] in inches diff --git a/SD-VBS/common/toolbox/toolbox_basic/stella/showim.m b/SD-VBS/common/toolbox/toolbox_basic/stella/showim.m new file mode 100755 index 0000000..10db297 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/stella/showim.m @@ -0,0 +1,36 @@ +% function showim(f,cmap) display real or complex image. +% When it is complex, the real part and imaginary part +% are displayed as [real,imag] in one image. +% cmap is the colormap. default = gray, -1 = inverted gray. + +% Stella X. Yu, 2000. + +function showim(f,cmap,ishori) + +if not(isreal(f)), + i = [real(f(:)); imag(f(:))]; + j = [min(i), max(i)]; + [nr,nc] = size(f); + if nargin<3 | isempty(ishori), + ishori = nr>nc; + end + if ishori, + i = zeros(nr,1); + f = [real(f), [i+j(1),i+j(2)], imag(f)]; + else + i = zeros(1,nc); + f = [real(f); [i+j(1);i+j(2)]; imag(f)]; + end +end +imagesc(f); axis off; axis image; + +if nargin<2 | isempty(cmap), + return; +end + +if cmap==1, + cmap = gray; +elseif cmap==-1, + cmap = flipud(gray); +end +colormap(cmap); \ No newline at end of file diff --git a/SD-VBS/common/toolbox/toolbox_basic/stella/showncut.m b/SD-VBS/common/toolbox/toolbox_basic/stella/showncut.m new file mode 100755 index 0000000..b1fe1f4 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/stella/showncut.m @@ -0,0 +1,92 @@ +% function [g,lgd,v,s,dd] = showncut(fn,rec_num) +% Input: +% fn = file / image name +% rec_num = Ncut record number +% Output: +% g = a cell contains 1D, 2D and 3D embeddings +% lgd = legend for g +% v = eigenvectors +% s = eigenvalues +% dd = normalization matrix = 1/sqrt(rowsum(abs(a))) +% an image is displayed + +function [g,lgd,v,s,dd] = showncut(fn,rec_num) + +globalenvar; cd(IMAGE_DIR);cd(fn); feval([fn,'_par']);cd(HOME_DIR); +par = p(rec_num); +no_rep = (par.offset<1e-6); + +[v,s,dd] = firstncut(fn,rec_num); +[m,n,nc] = size(v); + +% generate images for display +nr = 5; +num_plots = nc * nr; +g = cell(num_plots,1); +lgd = g; +names = {'r','\theta','\phi'}; +x = cell(3,1); +for j=1:nc, + g{j} = v(:,:,j); + lgd{j} = sprintf('%s_{%d} = %1.2f','\lambda', j+no_rep, s(j)); + + if j0) & y>0; + % showmask(f,mask); +end diff --git a/SD-VBS/common/toolbox/toolbox_basic/tars/TOOLBOX_calib.tar b/SD-VBS/common/toolbox/toolbox_basic/tars/TOOLBOX_calib.tar new file mode 100755 index 0000000..bb418a5 Binary files /dev/null and b/SD-VBS/common/toolbox/toolbox_basic/tars/TOOLBOX_calib.tar differ diff --git a/SD-VBS/common/toolbox/toolbox_basic/textons/dist2.m b/SD-VBS/common/toolbox/toolbox_basic/textons/dist2.m new file mode 100755 index 0000000..f2d93e1 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/textons/dist2.m @@ -0,0 +1,27 @@ +function n2 = dist2(x, c) +%DIST2 Calculates squared distance between two sets of points. +% +% Description +% D = DIST2(X, C) takes two matrices of vectors and calculates the +% squared Euclidean distance between them. Both matrices must be of +% the same column dimension. If X has M rows and N columns, and C has +% L rows and N columns, then the result has M rows and L columns. The +% I, Jth entry is the squared distance from the Ith row of X to the +% Jth row of C. +% +% See also +% GMMACTIV, KMEANS, RBFFWD +% + +% Copyright (c) Christopher M Bishop, Ian T Nabney (1996, 1997) + +[ndata, dimx] = size(x); +[ncentres, dimc] = size(c); +if dimx ~= dimc + error('Data dimension does not match dimension of centres') +end + +n2 = (ones(ncentres, 1) * sum((x.^2)', 1))' + ... + ones(ndata, 1) * sum((c.^2)',1) - ... + 2.*(x*(c')); + diff --git a/SD-VBS/common/toolbox/toolbox_basic/textons/find_textons.m b/SD-VBS/common/toolbox/toolbox_basic/textons/find_textons.m new file mode 100755 index 0000000..e7fa4b0 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/textons/find_textons.m @@ -0,0 +1,46 @@ +function [centers,label,post,d2]=find_textons(FIw,ncenters,centers_in,n_iter); +% [centers,label,post,d2]=find_textons(FIw,ncenters,centers_in,n_iter); +% +% find textons using kmeans for windowed portion FIw of filtered image +% +% to start with centers pulled randomly from image, set centers_in=[] + +% define number of textons +%ncenters=25; + +[N1,N2,N3]=size(FIw); +% reshape filtered image stack into a long array of feature vectors +fv=reshape(FIw,N1*N2,N3); +% (each row is a feature vector) + +%centers=.01^2*randn(ncenters,N3); +% take centers randomly from within image +if isempty(centers_in) + rndnum=1+floor(N1*N2*rand(1,ncenters)); + centers_in=fv(rndnum,:); +end + +options = foptions; +options(1)=1; % Prints out error values. +options(5) = 0; +if nargin<4 + n_iter=15; +end +options(14) = n_iter; % Number of iterations. + +[centers,options,d2,post]=kmeans2(centers_in,fv,options); + +% reshuffle the centers so that the one closest to the origin +% (featureless) comes last +norms=sum(centers.^2,2); +[sortval,sortind]=sort(-norms); +centers=centers(sortind,:); +d2=reshape(d2,N1,N2,ncenters); +post=reshape(post,N1,N2,ncenters); +d2=d2(:,:,sortind); +post=post(:,:,sortind); + + +% retrieve cluster number assigned to each feature vector +[minval,label]=min(d2,[],3); + diff --git a/SD-VBS/common/toolbox/toolbox_basic/textons/find_textons1.m b/SD-VBS/common/toolbox/toolbox_basic/textons/find_textons1.m new file mode 100755 index 0000000..b192015 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/textons/find_textons1.m @@ -0,0 +1,37 @@ +function [centers,label,post,d2]=find_textons(fv,ncenters,centers_in,n_iter); +% [centers,label,post,d2]=find_textons(FIw,ncenters,centers_in,n_iter); +% +% find textons using kmeans for windowed portion FIw of filtered image +% +% to start with centers pulled randomly from image, set centers_in=[] + +[N1,N2] =size(fv); + +% take centers randomly from within image +if isempty(centers_in) + rndnum=1+floor(N1*rand(1,ncenters)); + centers_in=fv(rndnum,:); +end + +options = foptions; +options(1)=1; % Prints out error values. +options(5) = 0; +if nargin<4 + n_iter=15; +end +options(14) = n_iter; % Number of iterations. + +[centers,options,d2,post]=kmeans2(centers_in,fv,options); + + +% retrieve cluster number assigned to each feature vector +[minval,label]=min(d2,[],2); + + +h = hist(label(:),[1:max(label(:))]); +a = h>0; +a = cumsum(a); + +[nr,nc] = size(label); +label = reshape(a(label(:)),nr,nc); + diff --git a/SD-VBS/common/toolbox/toolbox_basic/textons/kmeans2.m b/SD-VBS/common/toolbox/toolbox_basic/textons/kmeans2.m new file mode 100755 index 0000000..0bd87b2 --- /dev/null +++ b/SD-VBS/common/toolbox/toolbox_basic/textons/kmeans2.m @@ -0,0 +1,127 @@ +function [centres, options, d2, post, errlog] = kmeans2(centres, data, options) +%KMEANS Trains a k means cluster model. +% +% Description +% CENTRES = KMEANS(CENTRES, DATA, OPTIONS) uses the batch K-means +% algorithm to set the centres of a cluster model. The matrix DATA +% represents the data which is being clustered, with each row +% corresponding to a vector. The sum of squares error function is used. +% The point at which a local minimum is achieved is returned as +% CENTRES. The error value at that point is returned in OPTIONS(8). +% +% [CENTRES, OPTIONS, POST, ERRLOG] = KMEANS(CENTRES, DATA, OPTIONS) +% also returns the cluster number (in a one-of-N encoding) for each +% data point in POST and a log of the error values after each cycle in +% ERRLOG. The optional parameters have the following +% interpretations. +% +% OPTIONS(1) is set to 1 to display error values; also logs error +% values in the return argument ERRLOG. If OPTIONS(1) is set to 0, then +% only warning messages are displayed. If OPTIONS(1) is -1, then +% nothing is displayed. +% +% OPTIONS(2) is a measure of the absolute precision required for the +% value of CENTRES at the solution. If the absolute difference between +% the values of CENTRES between two successive steps is less than +% OPTIONS(2), then this condition is satisfied. +% +% OPTIONS(3) is a measure of the precision required of the error +% function at the solution. If the absolute difference between the +% error functions between two successive steps is less than OPTIONS(3), +% then this condition is satisfied. Both this and the previous +% condition must be satisfied for termination. +% +% OPTIONS(14) is the maximum number of iterations; default 100. +% +% See also +% GMMINIT, GMMEM +% + +% Copyright (c) Christopher M Bishop, Ian T Nabney (1996, 1997) + +[ndata, data_dim] = size(data); +[ncentres, dim] = size(centres); + +if dim ~= data_dim + error('Data dimension does not match dimension of centres') +end + +if (ncentres > ndata) + error('More centres than data') +end + +% Sort out the options +if (options(14)) + niters = options(14); +else + niters = 100; +end + +store = 0; +if (nargout > 3) + store = 1; + errlog = zeros(1, niters); +end + +% Check if centres and posteriors need to be initialised from data +if (options(5) == 1) + % Do the initialisation + perm = randperm(ndata); + perm = perm(1:ncentres); + + % Assign first ncentres (permuted) data points as centres + centres = data(perm, :); +end +% Matrix to make unit vectors easy to construct +id = eye(ncentres); + +% Main loop of algorithm +for n = 1:niters + + % Save old centres to check for termination + old_centres = centres; + + % Calculate posteriors based on existing centres + d2 = dist2(data, centres); + % Assign each point to nearest centre + [minvals, index] = min(d2', [], 1); + post = id(index,:); + + num_points = sum(post, 1); + % Adjust the centres based on new posteriors + for j = 1:ncentres + if (num_points(j) > 0) + centres(j,:) = sum(data(find(post(:,j)),:), 1)/num_points(j); + end + end + + % Error value is total squared distance from cluster centres + e = sum(minvals); + tmp = sort(minvals); + e95 = sqrt(tmp(round(length(tmp) * 0.95))); + erms = sqrt(e/ndata); + if store + errlog(n) = e; + end + if options(1) > 0 + fprintf(1, ' Cycle %4d RMS Error %11.6f 95-tier Error %11.6f\n', n, erms,e95); + end + + if n > 1 + % Test for termination + if max(max(abs(centres - old_centres))) < options(2) & ... + abs(old_e - e) < options(3) + options(8) = e; + return; + end + end + old_e = e; +end + +% If we get here, then we haven't terminated in the given number of +% iterations. +options(8) = e; +%if (options(1) >= 0) +% disp('Warning: Maximum number of iterations has been exceeded'); +%end + -- cgit v1.2.2 From 163c440444c74a4e0bbe0a8db3d1ca725413994b Mon Sep 17 00:00:00 2001 From: Joshua Bakita Date: Thu, 22 Oct 2020 03:17:31 -0400 Subject: Make SD-VBS compatible with run_bench.sh and cleanup SD-VBS: - Run silently - Fix some whitespace errors - Don't duplicate extra.h - Auto-detect if building with LITMUS-RT - Disable result checking - Add helper symlinks Misc: - Remove unused code from libextra - Set some missing rt_param fields in libextra - Disable CSV info dump from computeSMTslowdown.sh - Widen scope of .gitignore on .txt files - Include list of 2MB DIS pair benchmarks and inputs --- SD-VBS/common/c/extra.h | 479 -------------------------------- SD-VBS/common/makefiles/Makefile.common | 14 +- 2 files changed, 9 insertions(+), 484 deletions(-) delete mode 100644 SD-VBS/common/c/extra.h (limited to 'SD-VBS/common') diff --git a/SD-VBS/common/c/extra.h b/SD-VBS/common/c/extra.h deleted file mode 100644 index 8c67b33..0000000 --- a/SD-VBS/common/c/extra.h +++ /dev/null @@ -1,479 +0,0 @@ -/** - * Copyright 2019 Sims Hill Osborne and 2020 Joshua Bakita - * - * This header provides facilities by which to separably run and time TACLeBench - * To use this for paired task timing, define PAIRED (pass CFLAGS=-DPAIRED to make) - **/ -#define _GNU_SOURCE -#include // For O_CREAT and O_RDWR -#include // For sched_yield() -#include // For sem_{open, post, wait}() -#include -#include // For exit() -#include // For strlen() -#include // For mlockall() -#include // For ftruncate() -#include - -// This is only visible if _GNU_SOURCE is defined, and that define does not -// come along to places where this file is included. Address this by manually -// forcing it into the global namespace. -extern int sched_getcpu(); - -// These constants correspond to the imx6q-sabredb platform -#define LINE_SIZE 32 -#define L2_SIZE 16*2048*32 - -#if __arm__ -#include -#include -#endif - -#define LITMUS 1 -#define MC2 0 -#define MMDC_PROF 0 - -#if LITMUS -#include -#endif - -#if MMDC_PROF -#include "/media/speedy/litmus/tools/mmdc/mmdc.h" -#endif - -#if LITMUS -#define SET_UP LOAD_PARAMS SETUP_LITMUS -#else -#define SET_UP LOAD_PARAMS -#endif - -#if MMDC_PROF -#define LOAD_PARAMS LOAD_PARAMS_ITRL SETUP_MMDC -#else -#define LOAD_PARAMS LOAD_PARAMS_ITRL -#endif - -// Store state globally so that the job can be outside main() -// Arrays use float as a comprimise between overflow and size -// Paired arrays use long longs as precision is more important for those times -#ifdef PAIRED -long long *_rt_start_time; -long long *_rt_end_time; -#else -float *_rt_exec_time; -#endif -#if MMDC_PERF -float *_rt_mmdc_read; -float *_rt_mmdc_write; -#endif -long _rt_jobs_complete; -long _rt_max_jobs; -int _rt_core; -int _rt_will_output; -struct timespec _rt_start, _rt_end; - -char *_rt_run_id; -char *_rt_our_prog_name; -char *_rt_other_prog_name; -char *_rt_other_core; -#define _RT_FILENAME_LEN 64 -#define _BILLION (1000*1000*1000) -#ifdef PAIRED -char *_rt_barrier; -sem_t *_rt_first_sem, *_rt_second_sem; -int _rt_lock_id; -#endif - -static void _rt_load_params_itrl(int argc, char **argv) { -#ifdef PAIRED - if (argc != 8) { - fprintf(stderr, "Usage: %s ", argv[0]); - fprintf(stderr, " string for logging. Name of this task.\n"); - fprintf(stderr, " integer number of iterations. -1 for infinite.\n"); - fprintf(stderr, " UNUSED. Core is now auto-detected.\n"); - fprintf(stderr, " integer for logging. Core of paired task.\n"); - fprintf(stderr, " string for logging. Name of paired task.\n"); - fprintf(stderr, " string to append with .txt to yield output file name.\n"); - fprintf(stderr, " 1 to indicate this is pair member 1, otherwise pair member 2.\n"); - exit(1); - } -#else - if (argc != 6) { - fprintf(stderr, "Usage: %s \n", argv[0]); - fprintf(stderr, " string for logging. Name of this task.\n"); - fprintf(stderr, " integer number of iterations. -1 for infinite.\n"); - fprintf(stderr, " UNUSED. Core is now auto-detected.\n"); - fprintf(stderr, " string to append with .txt to yield output file name.\n"); - fprintf(stderr, " 1 to save results, 0 to discard.\n"); - exit(1); - } -#endif - _rt_our_prog_name = argv[1]; - _rt_max_jobs = atol(argv[2]); - _rt_core = sched_getcpu(); -#ifdef PAIRED - _rt_other_core = argv[4]; - _rt_other_prog_name = argv[5]; - _rt_run_id = argv[6]; - _rt_lock_id = atoi(argv[7]); - // The paired version doesn't support disabling output (legacy compatibility) - _rt_will_output = 1; -#else - _rt_other_core = "none"; - _rt_other_prog_name = "none"; - _rt_run_id = argv[4]; - _rt_will_output = atoi(argv[5]); -#endif /* PAIRED */ - if (_rt_max_jobs < 0 && _rt_will_output != 0) { - fprintf(stderr, "Infinite loops only supported when _rt_will_output is disabled!\n"); - exit(1); - } - if (strlen(_rt_run_id) + 5 > _RT_FILENAME_LEN) { - fprintf(stderr, "Run ID is too large! Keep it to less than %d characters.\n", _RT_FILENAME_LEN); - exit(1); - } -#ifdef PAIRED - _rt_start_time = calloc(_rt_max_jobs * _rt_will_output, sizeof(long long)); - _rt_end_time = calloc(_rt_max_jobs * _rt_will_output, sizeof(long long)); - if (!_rt_end_time || !_rt_start_time) { - perror("Unable to allocate buffers for execution times"); - exit(1); - } - _rt_first_sem = sem_open("/_libextra_first_sem", O_CREAT, 644, 0); - _rt_second_sem = sem_open("/_libextra_second_sem", O_CREAT, 644, 0); - if (_rt_first_sem == SEM_FAILED || _rt_second_sem == SEM_FAILED) { - perror("Error while creating semaphores"); - exit(1); - } - int barrier_file = shm_open("/_libextra_barrier", O_CREAT | O_RDWR, 644); - if (barrier_file == -1) { - perror("Error while creating shared memory for barrier synchronization"); - exit(1); - } - if (ftruncate(barrier_file, 1) == -1) { - perror("Error while setting size of shared memory for barrier synchronization"); - exit(1); - } - _rt_barrier = mmap(NULL, 1, PROT_WRITE, MAP_SHARED, barrier_file, 0); - if (_rt_barrier == MAP_FAILED) { - perror("Error while mapping shared memory for barrier synchronization"); - exit(1); - } - *_rt_barrier = 0; -#else - _rt_exec_time = calloc(_rt_max_jobs * _rt_will_output, sizeof(float)); - if (!_rt_exec_time) { - perror("Unable to allocate buffer for execution times"); - exit(1); - } -#endif /* PAIRED */ - _rt_jobs_complete = 0; - mlockall(MCL_CURRENT || MCL_FUTURE); -} -#define LOAD_PARAMS_ITRL _rt_load_params_itrl(argc, argv); - -#define SETUP_MMDC \ - _rt_mmdc_read = calloc(_rt_max_jobs * _rt_will_output, sizeof(float));\ - _rt_mmdc_write = calloc(_rt_max_jobs * _rt_will_output, sizeof(float));\ - if (!_rt_mmdc_read || !_rt_mmdc_write) {\ - perror("Unable to allocate buffer for MMDC data");\ - exit(1);\ - }\ - MMDC_PROFILE_RES_t mmdc_res;\ - memset(&mmdc_res, 0, sizeof(MMDC_PROFILE_RES_t));\ - int fd = open("/dev/mem", O_RDWR, 0);\ - if (fd < 0) {\ - perror("Unable to open /dev/mem");\ - exit(1);\ - }\ - pMMDC_t mmdc = mmap(NULL, 0x4000, PROT_READ | PROT_WRITE, MAP_SHARED, fd, MMDC_P0_IPS_BASE_ADDR);\ - if (mmdc == MAP_FAILED) {\ - perror("Unable to map MMDC address space");\ - exit(1);\ - }\ - mmdc->madpcr1 = axi_arm1;\ - msync(&(mmdc->madpcr1),4,MS_SYNC); - -#define SETUP_LITMUS \ - unsigned int wait = 0; \ - if (be_migrate_to_domain(_rt_core) < 0) { \ - perror("Unable to migrate to specified CPU"); \ - exit(1); \ - } \ - struct rt_task rt_param; \ - init_rt_task_param(&rt_param); \ - /* Supposedly the next two parameters are irrelevant when reservations are enabled, but I'm leaving them anyway... */ \ - rt_param.exec_cost = ms2ns(999); \ - rt_param.period = ms2ns(1000); \ - rt_param.priority = LITMUS_HIGHEST_PRIORITY; \ - rt_param.cls = RT_CLASS_HARD; \ - rt_param.release_policy = TASK_PERIODIC; \ - rt_param.budget_policy = NO_ENFORCEMENT; \ - rt_param.cpu = _rt_core; \ - if (set_rt_task_param(gettid(), &rt_param) < 0) { \ - perror("Unable to set real-time parameters"); \ - exit(1); \ - } \ - if (init_litmus() != 0) { \ - perror("init_litmus failed"); \ - exit(1); \ - } \ - MC2_SETUP \ - if (task_mode(LITMUS_RT_TASK) != 0) { \ - perror("Unable to become real-time task"); \ - exit(1); \ - } \ - if (wait && wait_for_ts_release() != 0) { \ - perror("Unable to wait for taskset release"); \ - exit(1); \ - } - -#if MC2 -#define MC2_SETUP \ - - set_page_color(rt_param.cpu); -#else -#define MC2_SETUP -#endif - -#define CLEANUP_LITMUS \ - if (task_mode(BACKGROUND_TASK) != 0) { \ - perror("Unable to become a real-time task"); \ - exit(1); \ - } \ - -#if __arm__ -// On ARM, manually flush the cache -#define FLUSH_CACHES \ - volatile uint8_t buffer[L2_SIZE * 4]; \ - for (uint32_t j = 0; j < 4; j++) \ - for (uint32_t i = 0; i < L2_SIZE * 4; i += LINE_SIZE) \ - buffer[i]++; -#else -// On x86 call the wbinvld instruction (it's in a kernel module due to it being ring-0) -#define FLUSH_CACHES \ - FILE *fp = fopen("/proc/wbinvd", "r");\ - if (fp == NULL) {\ - perror("Cache flush module interface cannot be opened");\ - exit(1);\ - }\ - char dummy;\ - if (fread(&dummy, 1, 1, fp) == 0) {\ - perror("Unable to access cache flush module interface");\ - exit(1);\ - }\ - fclose(fp); -#endif - -// This semaphore-based synchronization is from Sims -#define FIRST_UNLOCK \ - if (_rt_lock_id == 1) {\ - if (sem_post(_rt_second_sem) != 0) {\ - perror("Unable to unlock second semaphore");\ - exit(1);\ - }\ - } \ - else {\ - if (sem_post(_rt_first_sem) != 0) {\ - perror("Unable to unlock first semaphore");\ - exit(1);\ - }\ - } \ - -#define FIRST_LOCK \ - if (_rt_lock_id == 1) {\ - if (sem_wait(_rt_first_sem) != 0) {\ - perror("Unable to wait on first semaphore");\ - exit(1);\ - }\ - }\ - else {\ - if (sem_wait(_rt_second_sem) != 0) {\ - perror("Unable to wait on second semaphore");\ - exit(1);\ - }\ - } - -// This ensures a very low difference between pair member start times -#define BARRIER_SYNC \ - if (__sync_bool_compare_and_swap(_rt_barrier, 0, 1)) {\ - while (!__sync_bool_compare_and_swap(_rt_barrier, 0, 0)) {};\ - }\ - else {\ - __sync_bool_compare_and_swap(_rt_barrier, 1, 0);\ - } - -// Buffer timing result from a single job -static void _rt_save_job_result() { - if (_rt_jobs_complete >= _rt_max_jobs) { - fprintf(stderr, "Max jobs setting too small! Trying to record job #%ld when we only have space for %ld jobs. Exiting...\n", _rt_jobs_complete, _rt_max_jobs); - exit(1); - } - if (_rt_jobs_complete > -1 && _rt_will_output) { -#ifdef PAIRED - _rt_start_time[_rt_jobs_complete] = _rt_start.tv_sec; - _rt_start_time[_rt_jobs_complete] *= _BILLION; - _rt_start_time[_rt_jobs_complete] += _rt_start.tv_nsec; - _rt_end_time[_rt_jobs_complete] = _rt_end.tv_sec; - _rt_end_time[_rt_jobs_complete] *= _BILLION; - _rt_end_time[_rt_jobs_complete] += _rt_end.tv_nsec; -#else - _rt_exec_time[_rt_jobs_complete] = _rt_end.tv_sec - _rt_start.tv_sec; - _rt_exec_time[_rt_jobs_complete] *= _BILLION; - _rt_exec_time[_rt_jobs_complete] += _rt_end.tv_nsec - _rt_start.tv_nsec; -#endif /* PAIRED */ -#if MMDC_PROF - _rt_mmdc_read[_rt_jobs_complete] = mmdc_res.read_bytes; - _rt_mmdc_write[_rt_jobs_complete] = mmdc_res.write_bytes; -#endif - } -} - -// Save all buffered timing results to disk -static void _rt_write_to_file() { - char fileName[_RT_FILENAME_LEN]; - FILE *fp; - munlockall(); - if (!_rt_will_output) - goto out; - strcpy(fileName, _rt_run_id); - strcat(fileName, ".txt"); - fp = fopen(fileName, "a"); - if (fp == NULL) { - perror("Unable to open output file"); - exit(1); - } - // Baseline output uses a similar format with "none" for unused fields - for (int i = 0; i < _rt_jobs_complete; i++){ - fprintf(fp, "%s %s %u %s %ld", _rt_our_prog_name, _rt_other_prog_name, - _rt_core, _rt_other_core, _rt_max_jobs); -#ifdef PAIRED - // For unclear legacy reasons, paired tasks emit sec and ns separately - fprintf(fp, " %lld %lld %lld %lld", - _rt_start_time[i] / _BILLION, _rt_start_time[i] % _BILLION, - _rt_end_time[i] / _BILLION, _rt_end_time[i] % _BILLION); -#else - fprintf(fp, " %.f", _rt_exec_time[i]); -#endif /* PAIRED */ - fprintf(fp, " %s %d %.f %.f\n", _rt_run_id, i, -#if MMDC_PROF - _rt_mmdc_read[i], _rt_mmdc_write[i]); -#else - 0.0, 0.0); -#endif /* MMDC_PROF */ - } - fclose(fp); -out: -#if LITMUS - CLEANUP_LITMUS -#endif /* LITMUS */ -#ifdef PAIRED - munmap(_rt_barrier, 1); - shm_unlink("/_libextra_barrier"); - sem_unlink("/_libextra_first_sem"); - sem_unlink("/_libextra_second_sem"); - free(_rt_start_time); - free(_rt_end_time); -#else - free(_rt_exec_time); -#endif /* PAIRED */ -#if MMDC_PROF - free(_rt_mmdc_read); - free(_rt_mmdc_write); -#endif /* MMDC_PROF */ -} - -// Start a job -static void _rt_start_loop() { -#if LITMUS - if (sleep_next_period() != 0) { - perror("Unable to sleep for next period"); - } -#else - sched_yield(); -#endif /* LITMUS */ -#ifdef PAIRED - FIRST_UNLOCK - FIRST_LOCK -#endif /* PAIRED */ - FLUSH_CACHES -#ifdef PAIRED - BARRIER_SYNC -#endif /* PAIRED */ -#if MMDC_PROF - /* This disables profiling, resets the counters, clears the overflow bit, and enables profiling */ - start_mmdc_profiling(mmdc); -#endif /* MMDC_PROF */ - clock_gettime(CLOCK_MONOTONIC, &_rt_start); -} - -// Complete a job -static void _rt_stop_loop() { - clock_gettime(CLOCK_MONOTONIC, &_rt_end); -#if MMDC_PROF - /* This freezes the profiling and makes results available */ - pause_mmdc_profiling(mmdc); - get_mmdc_profiling_results(mmdc, &mmdc_res); -#endif /* MMDC_PROF */ - _rt_save_job_result(); - _rt_jobs_complete++; -} - -/****** New API ****** - * Intended structure: - * - * |int main(int argc, char **argv) { - * | SET_UP - * | ... - * | for_each_job { - * | tacleInit(); - * | tacleMain(); - * | } - * | WRITE_TO_FILE - * |} - * - * The main() function must call its parameters argc and argv for SET_UP to be - * able to read them. - * Only SET_UP necessarily has to be in main(). - * - * We use some niche C features, here's a quick explaination: - * 1. The && operator doesn't evaluate the right-hand side of the expression - * unless the left side evaluated to true. We use this to only execute - * _rt_start_loop() when the loop will actually run. - * 2. The comma operator executes the first expression and then throws away the - * result. We use this to call our void function from inside a comparison. - */ -#define for_each_job \ - for (; _rt_jobs_complete < _rt_max_jobs && (_rt_start_loop(),1); \ - _rt_stop_loop()) - -/****** Legacy API ****** - * Intended structure: - * - * |int main(int argc, char **argv) { - * | SET_UP - * | for (jobsComplete=0; jobsComplete1 input images =. # Variables exported from the benchmark specific Makefiles: @@ -55,8 +59,8 @@ COMMON_SRC := $(wildcard $(COMMON_DIR)/*.c) # RULES EXE = -INCLUDES = -I$(COMMON_DIR) -I$(C_DIR) -I${LIBLITMUS}/include -I${LIBLITMUS}/arch/arm/include -COMPILE_C = $(CC) $(CFLAGS) $(INCLUDES) -O2 +INCLUDES = -I$(COMMON_DIR) -I$(C_DIR) +COMPILE_C = $(CC) $(CFLAGS) $(LDFLAGS) $(INCLUDES) -O2 #COMPILE_C = $(CC) $(CFLAGS) -DGENERATE_OUTPUT -lm -O2 $(INCLUDES) COMPILE_G = $(CC) $(CFLAGS) -g -lm $(INCLUDES) COMPILE_PG = $(COMPILE_G) -pg @@ -107,7 +111,7 @@ compile-preload: compile: $(C_SRC) @echo @echo -e "Benchmark\t\t- $(BMARK)" - @$(COMPILE_C) $(COMMON_SRC) $(C_SRC) -lrt -L$(LIBLITMUS) -llitmus -lm -w -o $(BMARK)$(EXE) + @$(COMPILE_C) $(COMMON_SRC) $(C_SRC) -lrt -lm -w -o $(BMARK)$(EXE) compile-prof: $(C_SRC) @echo -- cgit v1.2.2 From a7c3210215bd1181ae93b23c313941dfb44519fb Mon Sep 17 00:00:00 2001 From: Joshua Bakita Date: Thu, 22 Oct 2020 22:46:39 -0400 Subject: Transform LITMUS-RT support in libextra to imply case-study mode Adds and parameters to benchmarks and disables cache flushing when compiled with LITMUS. Also fixes build with LITMUS enabled on yamaha.cs.unc.edu. Also allows output to be disabled, automatically infers _rt_lock_id, and allows for a specific pair ID for paired tasks. (The pair ID is added to all the semaphore and shared memory names, allowing multiple pairs to run in the system at a time.) --- SD-VBS/common/makefiles/Makefile.common | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'SD-VBS/common') diff --git a/SD-VBS/common/makefiles/Makefile.common b/SD-VBS/common/makefiles/Makefile.common index 9c28cfc..964ece6 100644 --- a/SD-VBS/common/makefiles/Makefile.common +++ b/SD-VBS/common/makefiles/Makefile.common @@ -30,8 +30,8 @@ BMARK_DIR := $(TOP_DIR)/benchmarks/$(BMARK) TOOL_DIR := $(TOP_DIR)/tools LIBLITMUS ?= /home/litmus/liblitmus ifneq ($(shell grep "define LITMUS 1" ../../../../../extra.h),) - CFLAGS += -I${LIBLITMUS}/include - LDFLAGS += -L${LIBLITMUS} -llitmus + override CFLAGS += -I${LIBLITMUS}/include -I${LIBLITMUS}/arch/arm/include + override LDFLAGS += -L${LIBLITMUS} -llitmus endif #The options set below and specific to each benchmark. Disparity takes 2 input images, whereas Tracking can take any >1 input images =. -- cgit v1.2.2

eoUhvTixRS}IboDc|:iKp€FnŒLl~PXQxsQ™‹Ki½wR‹lchI„xDyœRg‡[Q}]vmRr~7R‹dfyYoEU˜q\wUsr=eDS„SYtEcrDavHx|U‘CbµYa}YyxAaŠPwS[žVu~R~•J™ŸeyÀrožqi•]~Or¢Kc—Ub„Rb‰SYar‚Iƒ•Tr¢nXœhazUe‡Ae›M\ˆKqƒNeˆTOƒAaoCh~1sJ€ŒQ„šNªªbZÈtZXmvVp—[h›WeH^‰A_Ad‚E^GgBc’QV‹_NvNWh=`ƒS]‚I_t9h…Es‚;w>‰Gj Xy~LˆNxL{‹Cn•UŠ„lŠªQs®‘}…_e“Zb€S®€G‘¨hr®[f˜>h|?GwByj,u˜GzŽ=±‹I«Ô_¼®pÂÀn±Ét– blyf}f|ŒGs¥B´†WÀ益ٜi«w—›IŒ¬Œ§a§ÃSx¼q­˜L‘Æl­[fƒQW}>mx>¨y[‰È]ŸFƒtDhœW›“R¤¶Žf°ƒK‚¡^oŸL¢qX’€Ž‚b»Hri{“S¡”n©º~î«nÿgƒœH‡H‚§KŒˆ__¥[fvQxA_wXzŠ@pÄao‚KSo¡C…œG©I¥¿RwÃ]{šKo™Aq¡SV„Q{ƒE€X¿ŸPˆ±gq“Xd¡PZŠFo‹J| <ˆŸP}¼Ks’bx±`zªJ_¢Pi‹3o™Z}ˆJ–±Gl¶KcDsšEa”Lp§Rg§Xc„=dŽ7~¤Gw4{ŒX‘ M¬B‘¶I¡W‰¡@x«Dƒ˜C‹§IœÅf“Ì“®Öh—Éwæå^ƒ³U‡ FwœI†ŒSŠŸ]hT…”G™§@s¯bƒŸgÈ\Ž–Q~ N©aªÿskª>s˜Je¢?o•AWŠEy„Ux¨lt›?xŽT~¯S‚¬N…žWoL|¨Xq>k}Vo‰Cb–Mr“Kož[sš\{@uŸPh—>fŒ;`ŸSm8\„Jf€HkŽ@€š?]…9S‹7X}7`€Uf?n‹8a‰?^‚D[ƒCkˆGg–:Uq;[ŠEXu=u™Cv•QZ‰=f„?m§Az—OmžLj‰9‚¨A‘¹\s–Tx–Mf;^‰<^Šd’ElF…ŸO¸IuŸ\Œ²a~¡b¤¾l¶Úp„·Yh•TtŸam›Ed’@xJq“Xk‘fb”b‡•V’¿aƒ³}q”BW{=jƒKƒ·Z€ªdnŽAWxUžggœk]‡_m™@i‰>i‚8\l2]q3dsKtƒYy§_p†c~’Z… IZAaŒ`“~|xmRad­—‘´y—\‡ ny¡XcˆFi‹;eM[;I_K[}We…EaŠ?c~Gkˆ[ƒ¡a|˜Wn}QowWv{Ux‡JfvDWc:TjEkgGju?W}JgiJiz=^‡^cv_YnE]i9ns9b‡Fg‡RuMrˆHg‹VjnVp‚FbˆU_}Ty€Lv„KV…NOfJRi:Tk7UlAQlOXkEkrCmƒBU‚ZanFVq=MqCNf@Qd1Lf9`^:Lt6R]:K`0Va9SfALkFHkJ`eEsy;iŽKf‚\m†Ot‡QU€PUiL‰f9h­ZL‚peePf|8RŒWarV_wOzzKv‚Hn•`lŒbhCLŠbUkTbu8W…L[~V_xz†Qmži_ŽSWƒXYxR^€h‡N€“Ziž`\{>n=o;“Q‚”A—7lž@u‚9k¡CrH}¡F}“3w›Em{<ˆ¶Sr†BŠŸG~°u’˜i¼lšœX€£ZªK†ÄzgŠR€Z{XÝ˱§á¢e¨U††Bx¹PŒž\n’Iw”Iµ[†µT~²QrŒGm‰P™ R„Ä\x ŠnŸoq“Do¥Pp~Mh˜CkŽF}—=anŽEd=x”Xm‘Ir—HpKb“Flt?l¥Cv‰WnFyœ3Z‹;`O_ˆ@k†;l•3uˆ?fŠAŠªrc”s‘=gŠ5k†Ev”Sn’>sH˜c}«U_F]zEm‡MbŒDs‘?˜šPƒÈQp”O†¥F~™E’¾ZœÀde“S]ƒ:\7k…Grš@l”O‚®e‚£hmŸHn—To•bmšoŸÇŒ•ºr†»Yl›Ytª@{šBn“Bn“KhNhŠLmˆ|hŽadŒWb>W{5ZC`ŽMU‡D]„Du¨9Ih9Nv(rƒE†™N“¯Wc‹CKq3TnEqUx’My—Kcf@ap[`kV‡£2BU/?P9?\@h‡LƒŒiwŽdq‹Sa†YŸJo’@U|F[y9[€BPv5X{8Y~:a6WBWr=_8a}?eˆHwšP|”Q™NfEc‹@[xBb†Nlœ[‡¤U¡V‡¢R”³Nr•=c}>gRtKqˆK€•Uk…El‡Io‹Qx—e¤²m„›Nr‡Gy‹Tœ°j§´»¾k‘®tŒ¡c‰Gh‹Pu›pŒ®XyšR~¢VŒ¯W‘¬dŒ¯tÿzÔÄwÉ×m¬±i­h‰»Ÿ³ÞÉàñŠÂÍs²Àm ­y€žªžŸ™ˆzWN\Pf~[“ÃŒžÍ£¸É}t¬º¬êòÕñ¨µØ‚½ÌMZg8KW0JX5LhNf‹T[‡X€¡LrU}™Gg‚=b‡I]‡Qp“Rm…G\f9LWRlkI^l6CRLZl_ˆ¨kœ³\„”Zr”kvŽi}io‰vy‹{ƒ“rŒ˜Ur€9dj7Ym@mgBhs:R}OZgMfp@\qNalN`kAhxHoyCu€MhŠXxŠ]a‚F_`qiM]~E^}YjyLŠpAiƒ@Vw@NfGOe;Nc5Qe=Wm:UnB]q;vu@]SVxRWb@`oD\v9]j8Wl5i`7Ys4YeHXg5]a4Vi8Lg8N`8Xi9kp9j†Hi|^jƒQwƒUZQSuHao5a„C\tV^pDQw:XpH\m@lu9‰†G€žN‚œgS£hcwSZ~IdxJW;YqK]~Hil;dˆJ}ˆUw‹KfŠTi„WN‡[yp=l“LV‰ckuPyI^—`d…\[…bRv_Zm@`s=byLkVYƒ]_lJm|:]‹=a{ES‹LfsXT‡XSv7Uz*\v1p‡;[”GZ|Ejo?¤‰=o¿og…yluv3]›VL{pnsJ]‰EWTh|;{ŠYp“O`‹ZgGu‡@›XqŸ]r˜Vtœao“M‹“`e¬Y}}YtŸPbCj|@ª…<‘´Pt«I””^v°ZfŽEh‚2€6r¨l‡X„›SqŸb­”Fv±P[’P|~=z±^x¢gq‹K¦P²it¬Y_f~ŒgqŒF~„4v¡TyŽZƒ«Bq«n¡js”_u—Y—HÄ™†£eˆ˜^­¹8‰Ÿ]­¿H¸Ê†Äi¶œUÁÆ[ƒÝ›…”Oy…A€V|ˆR’=M§•K}‹K—}L‰>œHHž“=~š@{t@œœgzˆ”“N‡r[l”`´w5‰¹VxtRu~9‚ Gu˜S{Œ;r›O„•>s¡h‹žXŠ©i†¹uižX€ƒI\/Y~6o{1|Kp™;aœLa‹S[ƒ;l€:}£E`’P};t¦Aošea†Dq—<‚–ŒÀ=jLoƒ:a‘Rj‡DožPe’@q=l–-n~>r—Xj™]w•B}œC‹BÏöhÉOŒœP­D†ŠL~;s7v’B|™K{—>`ƒMt™bv“St’Mˆ«`x”a©h{Cp’;ަCoŠHb•Ci‹Gk•D†§IwžQƒ£E†³>m’Hs§`–µ{xŸbx¤S}²]ožX[„@p‘aŠ«Jf@kˆWfˆOo—Ip˜Vq•Vd‡9lŠ@c„@LoNf‡KRz+_~7Ww]W€Wg‚OHjCI`>_lE–˜iÕìçÿqŠ©Sgu:[q:jrKt˜$2I.O"@X8B^KjƒVs“MkŽElOlŠN]v]vPYpCvh>T†CGuRgd=[l@Jn;=cCUY>[n1dsAeoIb{OewS\x\aoIOn?Qj8Ym;Mi=Kg?bvCTtC]qP]v7aˆQf|Mb|Q^zVduGR…GYr;Z~>cZt€KT¡NDr[FfHSe9MwA=e8XU5gy@]ˆR[nKX{BcqD`ƒ>i€IUˆFdrHz„Fe˜K[ŽK^†=mƒIb–Fb„HkyBt‘6h˜kb•c[FdMhƒ<]‹2U‡Mkq-^‘8H‹a^iERu4]y:c|?S6`vDZ„UZyMM|ERo=ruE~”SrcnštxœP‰•Kyªaˆ¡b€ªJ‘¤Xv±c•“Q™ªu“»„‘³Vm˜qj”[w–BXšS‡~N°Q”œGs´pƒˆD«^w«[y˜Fl_z—Lx§M~–;¿¹X‹½ut§Q ˜=§ÁL£Òiˆ´l®£Y­¥`‰«[¶œSºU}¥oË£D“Üenžj_~K|{iŒ˜dw“V…–_’­z¹²NtÇ~Õ§„©ÕRƒªKt†Tƒ|A˜«j”–ˆ±]Ž ½ºU¥»c¥g~ÇU¶rÏÛ^¯Øa®•fš›Kÿ¶]Áÿ‹™ÉgªÁ\¼¼|ŸÒU…¥U“žVj Ao—?^‘C‡€?€©Ft‘P¢E€¤Wi–R„‡/{›A„Ÿ3m«h…Gz“T{ŽL²` Lv§?xšX†©BpHuœTgZf†@xˆNœ·Uˆ¸Q{Oi¢sT„5[ˆ@[uE^}6sBT‡Db‚IvŠTjDp“Ml”E¨hp¡T} Z¡¿}˜ÈvŠ£d«cŸQ¯So‰Bj}Lq‡q‡Zk˜9r‚B”I´Pt£MtžO¶ÄX¨Ío—ÌLw£Zi•NyœCz•M‰­I‰°J~¤H|–a„¨on—Qx°[p—_pŽOmœVušZm[—>z‹JŠ®xožIZwIt¡`|¥?}™I‡±N~ªQqFr›DœªR¼ïMlLVrCq…Xm@Z~Yd€Yz9[z2`}K–T‚¤TŒ¯Mu“Ft“IcŠJc„JnGfˆQn”OsYr”Z‚£jˆ³|­Àct™R}•I{–SŽªe{œm{ž`Oc“O‚W’¥cŸ«j½x¤½`”±U|¡’Öÿ½¨Ó„…·rŽ´j’¤i†œZ~£N{½Š‹²”“ÉœœÂ˜¹]n“g›À€´×mÏÞn²ÊxÀÓg”«…“À™Â’¶Ø¸Åðš°j€£l­t›ºg†ªUkŒC\v@LZ6GVLUlce„``l€žSa„N]|^ƒ p™³zŸ­a’W}˜pŸµaqThv|–~„ž|§uªy ·p‚™W]sf‚¢|‹¯uƒ GXh"^‘E]‚Z\xVShG_mG`yC_rK_wK^wH^R`lD]xHV{D`nIdwUgxJc„O_tOer>UrINu@Y`AUp;OmC^gFRt>BvEC`:YV+Pp4Re?Qf:\fBQgAh_Abq9\oHOrMWjEon;KGNj[_]=Rm=UlFKlDac;Sz7[iFTkAP^FUgCanN\pL^lGVo>Nd8]]7PnB@o>E_7Ra*To8WxIS{YNvQgqAZ}:`GT~[€?asDc€BXyIYwGRrBsh7^@l~TlŒIz˜MdŸEqGt•Uu‘EŽPo°bgL_ŠMY‚W\|CTƒ@g},b…Nˆ‡Me«0_‰Tlz>ˆ’GS¨P]pCl€<‚•<`›P[w:^n5P‚A_u[tˆX{‘Bp§J–‹`t·`jŠQs–Dƒ–nz¥ix£už™©fg±pb‹V†ƒB²Qz¤OošM” Mp»m~”O†¨X…§d^žb}|P‡©A¶yq¶ežGžªgw¶s…™g°p•Áoµw„ b‹™Y‘¿u¢¯Pˆ«z˜“S¹ÎN¥´¥¯º[­¼l®ÀUžÊ[¶¸lŸÛX‡³a‡qo{™ˆFžªtIJ“ä“–žZ«¥I›­Nµ›R“e…¬T„”a™ŠW•Êt’¤Lßžp­Ì­Ú“eŽÄZŸµr€Ç±ˆ•[}”Z«µ©Â‹€±]€¨Oz‚T”«:p¤Lxt2Ä­QnÎrt…K|ˆXp¤g}‹>•¡e¡ÆU®·Lž´V¶RxšbbŽ`dwKu„C~”Q“²q´Op‘H[‚‘Hy¡M“¸i£Ef„GbNŠ“Rs£\eŽGhŽKl’Pz¢S{‹U{§E~—\{©mˆ²qu’Sv’Eƒ•Da‰5hŠ?b}8iŠMf‰3cŒ3w¢Ny^p”J|PÁü™|ª:¾¿Vl»YlSx›\f”QnŠ:ƒOw>v—DŽ­W„®iŠ«[…§~†¡w‡œIn“Cm™V†¨]pXe\t“NŽÃOiŠKk“StŸ]pŽTޝL{˜Y’Ÿ^b“DsQtšRi‹GnLo‘P~¡Lq‘S‚¬h©Ö–Ñî„Õî|ºèzw«]g’`±w˜»e‘µJ‚W•¿~ŒÌ„mMX:…’_k—S|‘RmyL•¨Fl‹:p‰Eh@kˆU|šY{ž@Ro$5O!JZQsœMZs6ŠŽ8…˜R‰§Q|Jˆ¤a—­UVv;gƒ?n„J~Ÿ`g‡e²r«Z_„PpŽ^y–V_x\ƒ˜gž¯Vt—KsN…¬O’²F€§Hu’Fh‰Lšcy©kª\‹¢P‚œEc‡M—¢\ˆ¡O~œHªJm–Or•]™Àjp‘tžpy—Q{™L|˜dޝT~¤V~›Ml–GfŽPiˆQw–eƒ fs”q©Æpy™OjŽo·´™Ïm Ðq”±]‹°Y„£QФWŒªb‡£Vp™\Š¡h‡Ÿ`ˆ Y¤k¬Ò¤Ç眤މ²œ‘Ê—±º||}Š¥||˜‹€¨{u†\‹¹”ÒóžÀèqu•]g†MKm9Ie.@]8OhLVoAeŒ`’»X…¢P}i“³ƒ”½–´‰}¤ˆ†¤‚taX}O]udjŠwˆ¥z‰°„—¾‚xškRkOXpanqoŽbf{FV`&XŠXdvaY|KgtGn{Ii‘KV†PdoR\pI^qL]kAN~LPtN]fAgu>nŠKn•VjSl|NZ€M`sJoa>W9UePXk>Sq?QqFTh=d`-Rv.LiAOd>Rc;Ch6TN6Qd8JXDGR=UY5{a2l‡Ef[X=Vd:ai>isDosC^ŠLdsHSrAXZHdb6g{@njIlGUM`lBh{=]{CUtOEs@Xj-Nu6Sl=Mn>cqDfz=P‰AexJb‚Gi„SU|?VlW[t@]}[@mwLx•Kˆ“ae¯Ne†O\ˆCi{CfŽAmik‹H^‰D]@_y;x€8o“/w–Qn¡W^S§uL“¹Mh®oSoirCfˆLUTNy[Pp=}n5`’7Z€D}v;†ŸP‚¦Bgš]y‹Uk“pp›N}“Su§ZˆV{4…œ[n§k`‹Dp€B’žcŸºtžºf˜ºYm¦j””S…Ñe¤_|²\‚´9ˆ£f§_†ªmn™Sˆ‹N™¨o…ªY’²J™®ig˜|–[™¦dÌ•™n¦¸€aŸu›fƒ®y•Ÿ_J“†Œ\]¨§b°Ðf†»mu¨R ‡\[W›{*œcœ•P|—–¢Y‰¯c›®^‘§Kƒ‘R‘–sƒ—W|ZV~•M—¥U‰žY¬µw»¤p™ä„’¦j”’TÁ£A¹«nœ~Vr”`†‚N€Z„¦Xr”e~¯7¦SÆžh{ÒL°ŒGŒ«Yn’7‡”SƒžY‘›‚«®[¡²S“¦M­VÈJ‚•Fz•:q‡X€œkw–T€‰Hy¥PsRpšR‚ƒCs­XgŠPq@| F‚›Nº\•ž_¶¾S~ºe‚—F’ mîùàÏÿ®‘ÉIm €x…fž»~нpd‘gxœMm—I’–dަx«Èuƒ²S}¸„¢v€ŸVy•P{‰Ls¬ljˆJŒƒ8kÇ quTk’PdŒRlˆ4u‘=p‡I’”>q¨C™’†ÛüŸ”ä‹t‚Cu¶?…°O¶Á`ŸÄŒ…©OŠÈTo‰Ds˜Vx«g¬ªT˜È´bžYp Z‹¨T‚¡I–Ÿ;˜Õg“”;xŸ:j„7nšLl˜E`ŒCP1v‡;~¦{j‘KbTiŠS“Q»WuˆEz­Kkek‰@ˆ—Rt‹6—<ˆ£H˜<޵Vm™6xŽCj—Dg›s{™M½é¬u¥HkªZ~™Ru 9‹™Ag•_y‰I“£UšW•Rƒ˜dŠ£T{ªN}X™ÁR‘Ç\„¶lr‘Cw”<ŒPy¤Kg‰HwDe•Dm‹T|¢_~¢Pp“Xˆ¯Ps’^|¤U|›U­Vs—D‚¯[gƒV£] g‡µ˜r­n“c^†E^ŠClJrd”©a‹¸b‹®fk›bkŽJe‘Et•NjHo–h°kzd_†NiPk“O_†JW~Dc~Kƒš1\‰2^‰?cyNo–ni‡|l“_fˆQs™\{›r{˜aYs4d}T~ŸbWsEIaLlŽlb•Sg‰>RzUf‹TnŽLx‹^nTd‚_l”[²amKjEc„JiD‰¥]w—\ޤ^œ`jˆNmƒYšbq“Yq–^hŽThMu•SlYz“P†¢Vn•]¡¸v´Ì{Ôæz­ËXªUv¡JwžOj–Iv›Un”Kadˆ³ngCb‹Gjšx»’¾h…¦Yv¨o˜Ág•²Q‚¦X³J~¢I¥X¯a“³a’³h·†‡­egu]\‚^y˜œefƒqžºgˆšXmŒPpUo˜‘ˆ¿§ªÌtnIVv6Wu=i9lˆ8fuBNnIl”^wž[i‡b†´†°Ü‹£Ä†š¹w`pIfS?cD_wQqSep‹¨lv°¥Äp–¦W}ŒJe€WkS\sBHa:CX-YqNhnKZŽGexRlGa‘TZ„YThWZoGel>qxDW†LbxUo{DaCfŒLiŽU\‡VOaWkQth>w~B_ŠMYnSRj:Pb@hkGfx;\r9Kx@Mb=Zh6dq7Lh>PR4Fd5JU7JH/NY2[c3ps>sƒVg†LilDht:r}Nm‰JsŒ^yŒTd…JklSgt?n†Ch€K`IV‚QZzFm~@g‡Hc…[aLO‰@Ji?Ne4Ni;mu:f‰=U‡ZVrI[t9TwLkfGgHXˆUkuDr…DT“HiyByŠG`¥g_†_aN[ŠQqEc—fy=†q<”«Xs¾pœ{i’NŽ…A•«Yl«vW~^rzJŽ>«R|¥_‡¦`[³va€MFƒ4Od1po1uCkŽL’Ry¨P}›M—N¼M€¢Q€£Yu¥Z‡‘O®bkšSirt>aDVK]t:Xx2W~4UrDl„Eh—H˜’Rˆº]‚´bZšYazDk~DVŽIktD“ƒO‡·Ny§X‘^v“Oi‡@‹B†«[}©e–˜m‹¸[†±_‰°wv®gŽªe·dŽ¥_¥\­¦a…Äi—\{©eƒ¥v‡§R£¬Y™¾xsª[€i<•’GŒT†˜bW€dn€=Tt`Œ@u“I®"™ÈY¿¯Š¥Ån§§W“©Pn¢\yA›¥dŽÎc†¦Pt^ŒŽW¥b”Çu¤¬pž¯m¥»[²V™W¥°T–ÍS¦Ähz¿~š¤‚z¡„£qRkœP®¤Oy»\sO|ƒ?‡—Rh–O‰‰J¹H“¼OÅ·ZÿÁbé­nvG]ŠIoˆ:—±la¨q•>­`¦§€‰Äj~šIzªlŽ¡a‚ˆJt€@Ž’Fp¢JoG{™]o›Lk¹KoŒ=oœ^f‘aj:x<­¹`„¼t|ªQ…Ÿi‰«dvˆM™­X{°pʲ׀½`‹¤gu¬`›V‰§Ls?{’Fu¤G“¨SžÐF}­Pc„Vw‹PŽ·b|ÀetœUj„Qt†Yi?xœHq™c’¯Vn¤9‰£H|¤:“«V¶eœˆNŸ¼|™Îaƒ´ƒ³p¤^ƒ¡IŠ´l‘Áj¸ÂF®ç~q¥‚˜™JœÞTg˜K j|§p}–J\ƒa‚¦Vœºšºhr¾‡¡¬\‰±I{ GŠ«X˜Òe¨ÏPN~0deˆFuœM{[‰¬ytœLsœfoœLiMc€BeLd‹>|£Nu¢aºR^Ž=eVw¥OršYd‡NlŒRˆ§VŠš;b‰/”T…´QWiF£Qˆ¯[“Ä„‹³xx¦QkPw…Xc‰`SyFUd<]zK^„>];Z}F€›m¡f}“Ye‡BZy@c}Hr”p–·a€ŸAx™F›h~¡buU‘”b~•PlDkŽWrŽPx–KeˆNb†Kz Qw—Us›IeJc‡XŒ¨j²}Œª„u˜z{›]Æq¸Ï_”¬S¯i¥¿\i“DaŒJcNa‹Ft“Dm–b‚ hНgƒœTpœnt¡_k—Rq—YŽºj°Úeµàe¦Ùu¥ÈgŒ¤lš´aƒžFjŠN~–V¤±c„“cm‰gp“sn†Hr†4\yAlƒPe†uq`i‰>k‘?€¥Q‘µUx›C\ƒ;UkEmŒQj‰PjŒ]{ª‚І¶p‚ªOZ~r@Q–avjPt”Mt›[KjšTkŠ^f‰MŠLŸD§©Nn×t€iKŒAYfNn|@a…ˆ;¡m^‰\miXƒyATšE‰~p|­bn kgugƒQ_‚8Zs;gs.~Kƒ§Wj™Qo€SˆP¨™QyÃZy¤fr‘UwTbX6|@6O@TZ6zz-c˜FTxLx3{£Az§Cq“?R†Ei}Av‘Azž^œc]—WjƒAc’HdˆFh‰;^{G„…_j‘eˆ‘9ƒ²Tr YœƒJÁÄZ ×r¬cˆ¯TxžV„™[€›cš˜K‹¹\Œ—]„›L‡¨Z«¢~žºcxÀd˜^¦©SÌR¶«hÑÀXßd¡—I—´cȬZr¿jZ€?š`.ž›UŠÔy¥›[‚ÆmA®Á|”Áy¿¼ix½yˆ’<¥ >šÎs£ÀX­¾Sv²M¥ŸV“»^s™h©f¨Ûh¸`œ¬W—ªX’Âk‚ªc¥\¨©W£¸d©À^ŽÍu}©IyœiXŸOdsOq…Oh‹9ƒFºVÃn¬ËP…z¤œ}nƒ>Œ‹@f¤OŠH™ \~¸J”S­ Çn~˜;w™[•ŽLÿ¿aìÿŨê}”§†Ìeu—\Œ¡Dt»]gœF_y=]€@cˆ7|£@„£Vz›pv^žÃTq®\ŒK‚±o€XŒžHr¥Zy–g§’Z¦æoßÐn’ºNi®mt‰?‘L²c` |t•;†˜6ÑÉn¦ÿ„Ì¿U¡î]j£^›;z¯I‘C¹È^žÉx»¾Qœ¾GÍÃ^Éäh¹ÿg¤¨j—Ç’ˆ°O€°E“›S“Â`z½t‰©_¥X„­Y‰À]–žx…¸¡ˆ«E€šavŸ]¨¨BН[‚œN«»fŒ¬\~œU£”€›dw¨Sf‡Kƒp•Ëj™4„Š=½s¨½‡´Ôk™Ã†ÊÊnŽÛX‡»S·Uu™O˜¤h“¸Vˆ”Y ´z·ÖuešLmI|”P€Ž=`˜Vj7p‡N{ŸMe’duCp”aq‘Vd€NšYy¢e”©WzŒFg…T€žUŸX“ªt™L\}>X=^†KrOe’LzžE_;l‡M~¢^sœjx•Xn‹FhQu¡…žÌ‹‹®e޲tŒ»Yh’Ahˆc‹RjyKkN`ˆJl{NYŠAYzB\t7]@V|NdpPp€EmUdY[„ZhtM`‰@vJ•˜K¼Zd¾‘dˆjh~In{Fa‘Mm{:[ƒ?cAŠAƒš^w¤Xd‘Q‚Š;ŽOmœ]m}R}p=pQ`ŽObwLl†B|†YoŒK{…Ek>r†<‹~B~žT£q~“Wn@‰T€¡b]©vxxY–“@n¦Ri‡OZ…?`t)b‹6P€HVm9ww7ƒ•Mq«X{U˜¡Du¹Mk Xf”Ir“T‚šRp«Rs€F|’4k’Co“Ct—Xf–V€‹=•¯g·d•Á]qª…€ˆz© j”Òw‘©fªHÑ·SqêVŠW£žOÕÊJã‡h·[a\m…Hœ“YįYŸÏ¸«b޶‚‹‘m‘°e»­v|ÆqvŒ´À‹K‘ë]ˆŸViŸ_n“Qi…ZŠŠH˜g§šp§¹a€¥kšŠB— QÿÀ]ãÿš—íy°¯YzÅh‡VŸ±TœÉEŽÂg„¸f¤S…®\œÅc€À^‚©[‡­U¨¡R”È{†´¬l‰¥X¤S˜7uœ9‹—=pºLt“Up“d‰„[}I–E‡—Kž¸^z›dŸ™EŸ¬q~¹Z}’p®‹J”°qx>wD¨´Z¬Èe»ê°£ÿ³m¡ymi‚£fg­Jz“u—¨KbœHcŽ9n~=Z>xF¤]d˜JœVzŒY¢£[†µZ•ÈYy¤tžMi‹Nƒ¦T‚žZ‰¦\{¥p’¨J„¿]—¹dM•kto0vMu‡Aµk¨ÿÂyœ{š›œ—®ƒ†ÇU|¯a~¿m€¡ˆn¢†£µ±×ÞŽ½ÿ©†Ó˜|¥~áí‡Èôº–Î}‰«[x¤PZšT€®MyYtšly‡P{¢fxŸPu­\kL‰XsœEˆ¤b‚¥_°^˜¦z‹¡™º^x«Hp–B|D|‘D‡µr™h„C›´²×o•Ö™›Áwnœb­¤……Ò~‚£lu©Jd‘R…‹az¨h‘OŒ£q¦Á·L‰¨]‚©T~©Y|£Ax›C”Bk›M}–>w–DšW|±bƒ¾sm¢Ev“U’²„•Ÿ^~›Jy¨zФt†¹K¯Xy˜R›¾l—±ws mlW‚¤W€¢‚j¥OgŽXz¥dЍ]˜ÀarKŠªD‰°^¡ÍsqZa}b{œtgUo”Kx•Qf¡Y~Ÿ`…¤_Š©WeGeˆ;y“L£S\‡9h‚=i†?eˆ^€Bw–O˜Pv£Zz•OžOpšYp›^„¤W‚§j~¢PtKe?wFt‰M¢Dh‰OeGk‹U‹·^S~XHmGTn;n…SfHWxI_†F{“Wx¢Yy¢G{›WƒœQƒKd„>b|Fc…HuOr–=a€Mz—dƒ§e‚¡_{—KŠœNrTv˜cw›]Nt@`ƒ7[~KY#3?"7F-fe9tp:‚|Ic•O\WRwEZs=bu;g~>iŽSj_p’a}›pdŸbSYpoW]•Ol„jbuI`nLg}T]uJ`xEdjAUt8knRdj4fw@h|NU|SXfJcu{~O¢‹HgÁajˆPƒTnkNw{:qˆT~‹_°˜SÝŸ_„¢s…•q‚‘U‰‘bŠ˜c˜œh‡ž[y¬ggž_W„]grDdDz„Og„KeyXg‚PWƒMnrRu‚9dœQY}YVqGYtGTxE–wKa¤>Swlbb4gw=iƒEjŒI‚{@›šKeÂz_†cy{F|•GŽ•Ip§Z‚˜a–¯zj¬b•|Kz¤Lg’l|…CŽ•N~®N{ TtžWfœXsˆ\VCoo=[„Rb{Uw|6gŽZkˆJbˆFY|4c{?Š€<{œJ`žeouNs~IgŒ\‘}X•V_‘bh…WS’V‚iUW F\|Ft…E¥•T€ºSg¢e_„Squ:„ŽA‡°<}«\œ±m}»kz’g¨]§f[•GtƒE‹”P„¶ieŸZrK„“cf˜K…Ž;‚¥Nj¡Ru‹WhªoW—u[qpJwNÀ€:¢Ùˆš·‰£¯”ºÃx‘è§r©†•¢CÅoyœ™ec¹W€~F…0©œT«Ìqʺ_¶æy¬ØS~¿XÄ’\µ»ožÄV¶µlÚ×tƒÐ‘ŒŒSŒšA‹¦@®’W»·_ÏÏQÂìvºáeÿÞcµÿbÖ»cÆÿíµØ©œ¶nŒ²v¤­N„ák}ªh ¤YoÑplHƒœR‚°W£\ÿòPÞÿ§¢Ènr³[ƒ—]¥Ow´aƒ™X”§Cž@}ªAfŽM{ƒ7’´Q¸Mž`g¹oŽOŸ“X®¸rnÜ\viGw~‹ª^xžSt’cw‘QŒ˜GÅ¡GlΛ––]Ç纄¿ƒl‘8z–DZ}Ic‚7„šR‚—R޼L]™Qh4qšO]}‰QˆªXz˜M~œau™cŒ•xáý·lÖ^s“9iŠC_4‡‚S®K ´K–µqnœtfŠ>xŒ6PƒœF’°Z‚­“äÏr†ìƃ—TŒ¸_iŒZ d~´Kœr³¯|¬Þn©kb‚O„9ƒ­‡]•›x„X™³„~›_x=¡ev—G•³J–»_x«f[p?k˜ai—4qŸX€Wz K€¢J‡—p„¡J•J¢Üav¥E†¢Lƒ·Z£¦>¼g…œ[‹³k´|ƒ˜‰¯z¨âw˜±C|µ`xªYv D‚§Y³âN˜½S€µ]…™S{¤X¤°s àlp­S‚˜O~°Y£h‚ŸK‡›fŒ§Py²_s¡LwZj—FšP|²Z“£Y|¬_l“L€®Z£Žišzq˜R‘šw¢Êo‘¥ež\ƒœ`j•JxœVz©X¡¸Jv Y¨V³Ð‚šÓo‚±F¢`’Åz¤Øx‰¤\–°Kl–]‹¥Y|¡O{˜Ws¤MpUfŒNs ]tœHc‰R‹£ky”Hj‹=oŽTw’Gp~P€©q‘»Y“®m¥^rŸ@u”Rd…ct›Ym•SŒ°`qUr•Q^‡On–ct—FXl;…ŒU}•MyœV_YhNŸ:~—QŒ³_z¢4Xs,WpPu’a„Rlš6g…EdQyWg‹J„¦ipŸTsŽZby_ƒS]Qv‘SrœRo’Mf‰Fq›\{©Qe‹5`†6`}E`„VŒ¦X{šTnŠRb…CqŽOyd}›c€¡Ne‹Zh‘TnŽIr‹Pr‰Y‡¨s£ÆSj‰NoƒFY}@\„K]}C[|=c†\wœYt”F\…Ak“b~žVp›^‡§W| h{¦t•¨fp˜º‰›Ào‚¦xžÆwŸÃržÉn¦¹iºetˆ_†œm£É‰¬Ùy˜¶fšÀ^ޱV…™NpŽ:eŒMˆºUгW™­o¶Õg«Í^¡µI©Yƒ¶fÁÈÿ–Ãã`£ÄežÅXy–=hŽLs˜`{£XdZUhLQWFVeDcqIn‚Pf‚?HV$1:%4>0Yb<`v9jrFm‚M[‰_\~QSmAPoE]s>zAqŒQŽb‚£^c¦iV‡n_nXdq;o‚UcxUdrP{yCwQq‡OqqHbqFksNgm8_EhtLV}L\eBiiAs{Et„H‚Ng­YV„ZmP‚kB‘?n¦]‹a£“N€«bp‰cb}YgrQƒ}N„–b‹’i}šff‘jv‡fxYn‘PYN\‚Pk{Ez~NjŽQhUƒ‚N~šJt›_cˆWT|K^t;hv0„‚<^¡QY†‚qp=oyz¬JlŽbe„Ql…=¯¥k™Ý‹„¥Ly¤d±kŒ¨Dv³Q‹˜A‹·i‘6Ë“>„¼R†’O¥ªX–²Oœ´dбQ¢¨W|²l^yN£u¡W}žJ<ž´b‡Ðq”­_”ÆyW‹Sat6r}?…d­»g®¼x—Îm‰•xªÐn®ÃT‚Ën•Ä`}¥`¨ÊI¥Ïi‹£ˆ†³‡Š¯’‚·fzŒ`~©^„ Ts©_s\t”E|¤H†‘XŽ´Ly£k†½dXŽJc4yˆUuœAƒ¦Iz¤Qw…p§»n‰Ñst“F[€^˜˜‹{Ëj~‘Ns™Qm W„ P„¨]~’gŒ¸€‚¼Yt“KŒÁUƒp©`”·a‘ÊI‘¨F¤Ü{½}¥ºf¡Ð`Áñr‡¬X‘¥s®ÔKœÇR‚šM®[‡§j•Ÿu†¨td¥Ne‘We…B~U„´|xš]§[®N·hÄxemu|L~ªbu˜V’£| µo±\˜¯i„ Q޲R“²N‹¼kØõh½Ú{£ÐŒ´Ûi•Ái…¡i“Ãve™bl–M‚žTˆ¦Pš³g’·ho¦Oz›Fe”Dwž@u—OqNlP†”J‘«O{œTx‘Pz“T˜°RxŸKÈÅmm”HtˆUg‡Nd„Hl‡Ct—D¤]~¤fz¡Ke@d†?v’Zƒ¢R‰šLŒžR‹ NmŽLg„BmŽ@mˆNs–U‰®uޱLy’Dv~Fh€D~“]ˆŸTg‹>Wz<^zFd‰Hy›Zn“Rm”Yj—>lKhŽ]p”Hz–Ib†@Qƒ6?S7NeO€—@fr7>$54'~xGa‰;\†OmrIT†KeyUsyBqAaBnL|‡Mt\o’g_lOzkRkPri:j€Ak{Gi†Ud}Pr|Kz†PqMoyQx‚SqŽGl€UrwSkuBeeLym9oŠCh‰Q€T{P_cawU‰qDŽ˜K\«li~vl€K{…U}†_dŽVfpPnl7d†IŽy\€Vdon‚TxK`•W`{\[zPTkHH`8SnGbnKn~Hv‹V[‹§_q]d†Oa|Ei€<ƒ‡Jp”bu~GPu>ZlUztHm–Lo†In†Ts’gp‰H…„E¦«TƒÈhy“Q–—cŽ Rpžl‹†M„¡Tn§WRŽGR{HpoTy‹Kˆ˜Pw¡>’QyŸN~™bzžK†„L~£Nz™Q^ Uh€m…9t”Hs‘2hzFf…J[‹C|kR’‹L¸Drœ[d˜a’‰UʶLÝð|¿ç²‰Å}uµaŸh‚¦TŠŸOu•LoH€…KÁ­U¤è™t¿|l™\ˆ’X‰Ÿ`˜¦T„µjr‰d`xH’Œ6¼Àe—ÜŽs¯gm–dxN‰“]—§^¦º‰‚°Q†•C ±Z°¼a«¿{y«{”L¬£i ¿_¡Ÿt±£Wš¥e¤ƒ` ¬T‘ O£ eó«VÜÿÍÐÿ²ÉÓ”ìtîTàÿ‚œÿÊÂ’ù¡Á€²É©Áܧ}ݵq¡K ¨Ju£Z¤Tÿÿašÿ¢t‘^ЉP¦²\ŽÓ\ƒ·€n³„ƒ¦w}©…y˜`‚¨ey˜h°©b¥Èv}´ƒ›?x¬[‰¥_Ÿ°gw¦hxˆ<–±g„”}ª\~¶g‡›P‘Y®­s‹±gs›[p‡4q’?y‹G}®Vh‘Bw‹L_ŒHv„<‹¶|›Ð[|ª`¢l„ŸN™¯D£¿a}ž~‚Q«Rš¾k·®K‰£R”NÚàxªÿh‘·o¤¹]vžOˆ¯[¦¹d‡¤NŒ²g®fЧU‹°N¬¹fp¤Pj{4k†0‚¢EtŒet”[x°{‡“LÇ}~™Y³’O¨ÿ©âÍÒÄû~„®mÿÿ¡«ÿ}œÆcmµ…k‰BvKn”Mo”Zm™O\‹+„}\±¹Y©ò€¥^{¢i`€Fy<|¤EsŸcnMx‚;†´V˜°R¦Åk‹¸h˜´A‚¸J¹`Üÿm~Éc‚ªZ ºc±ß_†¿IiZ‚¨y—Ep‘P\z=™¦Qž½V{Âpx¥m”µjt§Q«W™Ôs§Óp§ÔoµÌu±ævƒÐƒ–¼ž½|•µnp›ni‰G}¤Sq K »I„¸FŽ·fpœ?€§]œ¤r€­l…©_z—?nŽIœX}Ÿ]n˜cv˜j—°Xvœ`{›g“Àr½z’nzµ‘{¦kjb®p‰¾h€«p‘¥…~¤M޲Wˆ¦`–Âk‹¬u–ÀpkB[~@†“C~¦U…©Q°Sˆ¯Zw`¯Ìn¼îd·M•ÇR º´¾åuæÿây²KˆŸU‡¢K¦Mu¡R›£_—·S¢K‘¼b‚¦\wœLw”N}Ÿc}pvšjx¦Wp›FxŠ@„‰KsŽ@uXp‰`›}”«_w”P|“Rr™h€œ\t‡Is—;[‡Gv™GeI|Z¹SxœMp‘Ma…Cl‰@]‚HW}Bvš>w“Db†P`‹[k˜Kt“X„¦aa€QW{7X„GXEa„]‡§{•°Y{œUr–`‡£`ž_u¡o†°yеuv—Sy˜Ip›b{¢_|¡d±^šÁw¢Æc¤Ñds¡Kf‡D`‰@YyKbˆMk’=[t?oJƒ•>b[‘¯m·n‹¢KHj@eŽa—·g€£†Ÿ»|ƒ©b°[t g‡£Zƒ­l–·{¢Çw›Ë…­Ð‚®×„«Ïk´Úl”°d”»t°Ö˜»÷“§Ôx£ÖŠ­áv¹Yk‘Ir˜Jg”Us§y¦â“¸è‚¸áa°S€²Sl€I@\MWb@MW3PQ-UL+HB*CS2KXLmˆY›3QW#40€ƒHl–NZahoNntB`~I~xF‘Lz£TY•ejrWc{QSƒgIhSY_POkI`hAq|Qw;f‘I…¬gu¤g’µozžYˆ«k} b¹l}¦_w˜e{¢Qj’Q\„ObLs›a¢ÀsŸÂc‹¸€ŸÈmjK¤Qy›Fg†Iz§W|¦H_}ErŠ`’«Vq˜`’Ágˆ®\d„?[zApœoˆ­^zšo~¨kŽ®n„¢OeŠI`ˆSw’i‹£wduŽn~šxx£{‡­r¡¹o©l‘¼ƒ˜Í~‘Ç…¨ÛsÄ}¬ØzÅóf¦ÀXu Hr“Nlˆhˆ±–ÄtЬ[¤[“Âe|Š+2@:GYBcoCor@ZP3KK.FaYy’Fe{/IPsm?\~MX`XpOmo>T‡?_lQ]wIl{TXmo~`^r:^oMXuOYjIlvIPƒLVsNanDjlG`U„€Ag“XvŠ^r…Y‹ˆY‹žlo¤p|”c„‡UuO€¡]}”Xp]nek{Ua†TKhZeIWo3OyFaa9gq9_‡G{iIzO{qo\g‡]rxTsIr™ru’h\^fxPo{@q~Oq}Hb{?eyDjw8bŒKb{D`…FZƒC_vIbzBmwFl}HuwI|–I{’T}’Yy†PoLS‹X]jMjxH|_Š[Z«[k~[o”Vxi„…Ox€S”ƒA•°S—«cš°yo»ƒc•t‘}8i¥Zƒ‹Gg¤R]“noOw“^‹›^s©Yˆ–\„°prŸf•ƒJ‰¾Td©mv^¨ŠH™˜6~¤q¦b‘»M®¨piÏ|‚bnCZ|Oo:{™}b”|lWgŠB’I…®RbZl{XkFq†C—›arÃq…Y“¦jr³n~a}¦`x¦o“˜Y£®V„·nœž_›À`t©aˆ‘H’®V™ÌZ—¯|f³{…„Pˆ¦d~¦f˜ži‚³]xŸp‡‘]ŒN—AÓ¤Nšßg‘¨cx¸p„›džœ@¼žiÎÑhÞå¹êŸ¿‰‘¯lÿÃ}o÷„rv½±d’Ñ^•­K«šZ‡š^Ÿµz‘¦]‘ƒ†–¬W¢­sÆÆ¶ƒu U¤ˆ)ŠÁ8S®•¾cb{Ûr•ÊT³©zÓîmzõ¯|Vb§:yyA¥OÏ„gŠE‚•3pƒJgˆ˜t‹t˜™U›»eŒ¸fc´‘x‹Fp‘;Œš@{¤BŠ¢`lš]„‘N‚fh—jš \Œ½{‡žD…±jš²\¡¡my¡u„ŽKÁ‘Mi¼i6Š«]qœX‡Ÿ=žŠdÇÒlóe¿~„¹Šˆ¤F‘Azœl‰¨p˜ŠF¨°q¡µm}§v¨«Œ¬ÑÁp¦jŽœa{¢Y’™n£Y…Ϭ´e™ãmw‰X±±D¾ÝjÁ[“„]¨¿r‡˜Iq‘@ŠšRgIt‚?›•Aq‡Kƒ¥6`“GƒJÿóxµwvX­«I¾exŠL‰¤d†©oÛ¡m¢ÿϱZ„ŸPvŒBi„Ui|X§”`y“€œ¯‹bˆ[ˆšF”·K…½<„ž4šÌ\‚ˆBq±@€žU‹ºbš¸]u¢Mw—`¯£¨Šº£‰¼}¯`zœA¢¿ï²Õ½±ÎzƒÈ_^{C°ž>½òQ‡µ_y¢Jy™Uv€FnŽ@~¥9–ŸSp‘Gx˜c€•^{–A•­”¼h… y𾇥¬J€¤Xƒ˜pˆ¨}š¼p¨Wxš8¤ÎT޹VбZ˜Ácj‹^}‘X†¹ht¨M€œRbˆL‰ž[g–M|’a~¦Q~Ža’¯€^Cs‹R}¬`…¦\­Yˆµm|ŸX|£TœX«\z©Oh•Wmˆ]~¤rx—]¡©Zƒ¤P´Ù‡”Áf†«^~¡ZdŒ\r¦q­mŽºT´E¬gjŒW…Ÿyœ±`wŽHfLPvK^€Hw£]s£o…¤f°Èbn“Qj‹a£jŽ­vz®vž¼`|[‘¶y‘µqÂv‰¦X„·dzšW§Y}Ÿf¯ÍŸœÂ‚‰¢dt•Ro‰`˜·a„ªCg‰St•GUu7gˆT’NjˆNfJ[JjŒXkSg…=g?kˆDa}AfHr•bp›e`}G]„IZƒJXx5aˆIu¢LgŠ]yž]r˜_c‰Ij–]d…Us–h‚ªT|žXxªSmŽOh‡Fp“SuœaŒ¬u¡Ëi–¸oޤWwˆXƒ¦vƒ¨d{£u½Öy¢·^®Z‹³i„šUw–W€¢tˆµQs’Ar”Hti­^zž\pŽ[j‘dz¤Ir>jƒJr•i¯pªMhJmQn’R­m…µbt˜\n§tˆ®y•¾‚µßˆ¬ÓŒÅøšÊö·ØhÄV}±QlŽXo‹d‰®Zm„@T|\€±u˜µ5We/gEl}LDX=JS5BX/AY,Kb2I]F]ŒQ…›Dgk/^k?Vj8ceHiq;t{GdˆHfuRuxN~vEbKh‡c_}J{lKp‹Oh‡Zq{QU„Qk¢\•‰Lt¿ZK“f\f;tz@‚‘Kd‰NstR“Wj±Y\…¶[_œt‘sP¹¡Loªe‡›jœ¢N•¿fµºu¥àq\²{ewDs†Lq“=aˆT]|M]|6…=†¦[s›O|ˆJ‚DŒƒb¡X¬[Ì”_t¸m’j¢Òyw­gu‰P¨±X´U„’[‡—=}v‰‘@½‡M޲Q—vw®nx’€¼Ç~‚ËG‰œW‡•V‘«G”ŽJ¤f—®PНMi²P›’B‚ÊlŽ…=¬ñrѽU©ÔGp®q—›E»ËŠŠÛa®ªg“Ïž|™s‚–[Œ¥fƒ¯I—œ;y bx—L…‹,¦ÏzvŽ=¨•TŽ¥P~ŸFÝ‹~ÏYŒœAª´\‰œZv²G—˜Y ½S°¹t’ „z¢Rz\†—R_…D€|4„w‰‰HӿЕÎf¦²k Ê’kºHos.•žR–ÌP‡´†y—ax’I€¨Q}¤R˜Z}„VjVU‰UiuZTŒP^[.£´~–æt¡©Rt¥^‡¡m¢§Ââss£:ƒŸNy¹Up‹:x•Xu“GÈOo£D¦¢\¹Ý`·éoˆ²`ÇÁu¹åt°Í”®ØvœÍXŸºe•Â|€´djZ‡ªž½d} bµql“SbtQwŒYvŽN‚šTp™Ln†QtšEt’Jr–X~¥i{œUsŽR‘²`¯e‰¶gœÈu‚žVt’P³zž»}¦×u€¦L‚™J‰©P’´M„©O‚¤W—ºe…µwx¨\s“^y–Ye™pƒšth“[Ÿsz²vxd‰µU¢Ä{œÈe˜ÌVr“=ˆ—5޲EŸ¥VªÖZ´ÄqÊb”­Pn‡C‘ž]€¥]ƒª`¥gƒ¨g„¶`|gqš]vžl£Åj•¶Z™ºc‡©O}¦r„£o¨Òs€KƒŸJwœu¦½Š³áOg‘Tq™=\ˆMfŠIs˜AWz:\„;l’Fp•IfŠb{Ng€[lzFzwIq„KmŠWu‚Xs—a_yƒOg’Rm}enBj‚TUnQmkB|>o•J\‰SpqL„†I{ŸJ†ŠX\œU[‰ek4|‘4u¥\]ŽZnhFG~A]c=xv8\’NtQP‘W_jh‰xV¤š_}‘kˆ›Zj£Ol‹Vt‹Db“cojanwBh‡EnEj{Ivt4u¤?¯™W¶Ô^ÄÎk±ãq¾Ãp¾«W§È‘Äu‰¹Tg­ojƒT¥œOiÂy‰ŠU‚°Ht§Y|’H`©HQ‹Tvo8k”B’Vm”M¦L”žHƒžQ‡‘N~­b™Hr¦T~JWˆ§B{šAvždx“m‘–[f¯{l„Fƒ‘O‹§Y«EƒQœ›k”Âi³«fÇp˜½`v«_ŠšLu¬T¨ˆT˜¼f‰¾„¡±dh´x¤sK¡Ë‚~´€“©o›˜Qæ˜f­í«¿ˆ¦hôPxÛjšU‘¸]€¦bÞÅ\Áþi¥ÏožÄ}®^•£cŒ½n„¢žˆ¦[O¢AtU‘*…ŽNšŸT°QŸ¶l–Fª¼uœ¾sf¡d{€.ÉŒ?¥¦Hj–P™U¥Ák`›a|Œ/m”Auƒ]}†@g@c~C^v2«F›Ñf™¢\v£ŒŒy¿Ìnж°†­j|¬}l‹Tx§8¥„D„«w¥¹B…éas’^j—:}Ÿ`~¬{˜NŠ—MŸŽb‘Óe¼»\½Ü‹…ÍU{§aЇA•¢^˜Ãr‚ŸxŒªVsžRŸ…;~Îq‘ŒC–µau¢H€<€ªaz¶U›¦†Ôß·ªé¡ÀØi³ýh—Û‡¦wÃl}ÁWA¯ÒIˆ«Lˆ¶q©e”®S…ÎHjBšƒYlyL¬Z’±KœŸXª¶cƒ¤L}H£¬`w¥Jy—U˜„_»Ô}v›g…[m SŒO–Î[‚¶GªE¦Í_¨½sŒÜœ¢¢‡íñs¿ÿ“…«Rl©G¦¦F˜®sµí‡·Óf} ‚©v£Å\ˆ»R¨]q™d_ŠDd‰K¨7z’>zžS°ªPg‘J‰¸f¡­¥“Â¥®ßuž¹W˜Ã^†£X«W…™Y’¾gs¤ZŠŸP¹h’Çn¸Â£Äá¢Þø°¬õŸ‰³h´Ç§¶ßªšÀzpžS’¡\u@ˆ«PmQœ–l‹¶S…¨U‹—F£XwšSi—Sx‘Nm{O—¡_qFcGi‘WsV‘±iÀÅw{²f©Y»[~¬MlHz›v޳€®ÈŽ­Ð{gšY€\ƒŸa‹¿[˜Y±cy¤c‡£_€§Q}žR~°E\xMf‡P‚œZƒªV—½k‚´e‰´€ ¿yªÜ•ÁßeyšK›¦b¸ÔzÝûŸÇ䫤¿ƒ’¯u—´]”¥X¦c²»j‹©tˆ¦jl™Pu_‡§XŠ©`…—^‹Ÿ[xžb‘±h¼l‡¬b‚¤q†¦Vv–ZbŽL_|yвœ˜ÀP_ŒS]„FZ‚?jHfŠAlŒNt”Xq–OmŽ?‰•Xn’Ci‰AYDUw:W|C^‡Hp‘Pi‘Er–\y¢LeD`ŒLi’=`‡Bm“Pr›[kŽQt˜n…«`nŽ^k—HjŽaw¦sŒ°[u–Sf“i§oŒ¬s‘¨`r”IjHsPx”Rw’^…¬~Ãp„¤ft]c†\jŽRoŒ]z¡]xŽHuQt‘aw“\y‹Ti‘SeZz‘Ol{Ei‰Gb‚B`tCeŒVs¢o•Á‹´s†§Lm’Rt‘Ru_ˆ–g¢|‰©¨Ù”ŸÂ|±£Ç{ Ò…©Õz˜ÆŽ­ØŽ²ØsªÚv©Þw™Íq§Ñl ¾h¢³T†›GnŽOb€TVkd†§m£²ayošÇmŸ¯©Ò\Ÿ¾v—¸`«°a‹Ìh°Ì^®Å[Êßkêÿp°ÿ¡ƒ½qœªG¥É_¼ù`qÆ~n €œ«`¬Ág‡¿rŒ¸a«·_¾ÇoŒÄnŸaŠ£d£W‰’k®K‘¡yƒœW„˜;‰?ŽŒy–Žc”™n§¯b˜W¥±Fs¤m‡Gœ¡M§Ã~·®zžç€†¿M–·N¯5–¸“¦°_¦×pÎɈu®Oi‹?{œy}¬”sH—ÃV±w†Ç…¿s âÅ™¬b|Ò†Š’W’Á€½j»S±Dy‹Fd‹M…‡²»{»ÈgÝÿ’޳ƒ¬Êk¢˜y‰²mp‰ƒÀ©W´p‚‹[·æt•®r²…j“JŸ¡bŒºƒŒš}Ÿu˜Ê•†¯ŠŸÃs¢©`s˜ar˜W‚¨Ww’Aw›j}‹Vy”Lƒ›W¤]˜¦m±Än¼Zt†MšQ„³WŸËeXˆ? ³€‡¿_ˆ›Jƒ IŠ¿I ¢jˆÂŒe]”©†ºj‰¹n}–K¦e¢ÏiެoŒµbþWµëq„µchˆQy…i§g‡¨aÃZ‡£\j[‘¤O™¥Kh™JoŠg–¹lŒªp~¢jh“^{ €…§‰~«s¿i°ÄwÝ÷›ŠÅ—ƒ§[œÈÂÛ¥•ÀVЦ\£Ìb›¶d ¼h®ºdmI‡—fÁÂw¤¹b—¥g‘´S¦ÂnÈæ{‰¦`q–K|šPn›St–Te8Rm@o‡m˜©mwŸ<]€Žb~ªYh–mw{Rt…8z}F€ƒCi„I‡tAiˆQŽ‹v{—P~ƒV}„LmMdŠ`YxE‡k;‡—M‹£fdºTt†Go”IV|Vup6k„E‚}=™—Qµ¸aŠÎjˆ¼¡m§nž|=§U²„¥d¸d‡¨Z¾§[‘Ђ²Ž¦µSÁ̓Æî•ç­‰³€•®c‡»ŒŸ¤l‡¸cnŸq¶šo˜Ñ–~µŸu•|ˆžvƒ¡žà˜•õ}‡»’i£Y‘b„m¡¯Q ½œ~Æ’až}†‰Q³´T¨ÇS‹Õh‘¥pž¤l¯µV“ß‚—Ärp°a‡Pv®@¥šgªÇ}‰ÁƒŒ³vp°jŠ•cx¬^k‰NNPm½bkƒdj„>‡‹8y¨\fšmhˆQ³~M¥¯[¿Å¨¿˜«ÇÒ °µ•á}¼Åˆ¢Þº³~£”EÔâl†÷¦˜¢š¿³¦˜ê›Ž·y¸Æo¿ß}˜Ð­µÁz“¯‡±Xv–X‚Šs‘Ve†N~;‘–m”е K»Ï|¹ƒ©½j´ÕS³ÝiwµcZiTv{;›‚<•Ø\Ÿºn‹¡L£Dt·|¦“a¥ÞZh¡{¬§…sË‚…”g·£y·Åį®z·@•™WŽŸŽ®Ïp¦Ùˆ‡­J·†<…q¦™StÇ>Š“;”LOƒ—9©w“?² G‹´ŒwžW¤gltR„«TŒ›€†¦_pŠ^­£p‘Õ’É|ޤc°Z–Ëx´ZvÂ`“·_œ„õÆj§öÞÝ…ŠŸv~ªM‘Ôtl‡q`^–{&†Á=wƒa•¬Rv™W“›d•·vœahyRzšLЇO—§_v‡J»§Tšälx´Y{EưN´Çh›³]¸°Q²¾`ÊÕd»Ø\‰¤EmŒQ‰„b­Àp­¿rªt€¿ˆl’Y’”\|’^™®n’¤g‹ªOpˆ•žG`¦Lg4kˆWl~@‹¨M—¸]™¯°v­`ˆ—\z”tr›yz”Vm•JlƒIy’W±½q|¦…•¢mËæyxÃ?s[z”U“»a£Ë`ÿÊzx”aŒ–[¯¸•²ïƒ{¬VzžO¥V•­U£Q…¥a†§dŽžM•œY¢¸SˆŸS“¢T‹¤^r‹7s“PxšG|˜C™g„¤qo£vžµ¤àn¤¿[š®nw§Xn€ouCkq‰—wz›V‘”rо|n“Pj„>j=pW¦¹qªy¥Éx—ÄŽz—v¯g¥ÍwˆŸl¥¾tªÔe–ÄL}Wy›Y‡´tn”Wˆ¸]dYibp‘g›Ås¡Ðk¤Îc…±elŒElNsNvš\³i¶às™º‰…´¤Åãz}±ww |Žœ|ïÿ°ÿÿ“Þÿ•ëÿs¥´l”´Xh‹A«°i¹Ôƒ„±i—²}¹ä‚‰¾¤ŒºŒ¤ak“T{§]¢bq QdyAg†4qJ‰ºy£¾IužKžD¦JeA\‹@Y‚?X:c…Hj’Nj’U‡©Ig…WÁ߈Åá^¬ÁKwŽG~ OgŠM‡¨wÌá~‘¯K_ŠElŽUp–Z†¥^ƒ«mžÃg‘ºb¦]|¦ReR\‰So£g~¯Sp˜[„®{Нy `v–Cd†c­`}¤RmŒA]ƒQmšfŠ£b™^‘¨X~˜Eq’[vœ_}ži•¸_€™Iqža³x—¹rˆ§yÃ{‰§InŽJp™HyL‡¡]¸t“²eŸTl•Zz›Xo“c…¨]„ŸIy”P j–«d®s‡Ÿm†¯f‚§_g„`~˜cl‡[U{l{°v‘§n†£j}œ]{žn˜Ç{±Ëc¦ÂO…£I‚”K|Dc€:UrYˆ¨s¸`RIRrSSh9Sl:Wb8_t@ew@k|MgfRz{D‘ŒA]v¬ln•en‡`‰‚JT˜PZm_`h>[nB`hCewJjHp…QiƒMg…^sˆ]€„TŠMŽGƒU}ˆGu“\aƒTllG~yC_?fv^u…Gs”Z6‰PIH]TZ+SnD…fPŒ”G_³vo{Z\„RauFxz:}œ\yVt^eƒWl…C«{V…Å_}œ‚x‚Rn‡M…|Dˆ†Ji…[m†RowGŽ{`†œU—šfx[VT‡}^”œF~¥]”yR¬«Z”¹||¬Zq˜Xƒ†Y€’CqžQZ‘S€{NxšQw“kin”^œCŸ½Y¾€v®b¥®qrÆ{}™‰‚˜v‰šqr©\‘h¬–{ÍŸ|›—„¥^~­r‹¢]„¬hˆ«h”«Xm¿r‡ƒ`˜Ÿcb½\‚wP³—H»aœzMruSb@ˆq0©°F›ÛjW¡•€rK‹•8yªi‹žy¬¦ŠãÄq°üŠÅà’”Þ¦¶—§¨wÇdoºƒe©©nwÑ•yžmUŠ]izPg‡M±Uƺ]›É‡š²«²n«¼VxÔ`o”bИGªÒP‹®a¤§ZÓ׊ަ¬^uŸ|ž‘Pšºmðl»éfÁÓ˜jȼ{ð¡·´W°öƒ{Ç—˜§U›°‹“±’wšž™}]°žY–·xkŸVŠ“5„¡4V—DYiIœ‡Cš¬fã°Sy䞊žZ´ |®¨œ²c‡¤n§”R³¸@§¥‚}§´•Y£¯w‘Áh‚§dy f‰Žr… qœ¬PuÊ]€?w¢]¨Œn¾Íuw؉¤Se§cxNn•^‚›p…W‘â?¥¥m¦¡¨›©VެdžÀRoÎ`x¥`‘¦IË^ˆ¡XzºO¡Ÿaœ¤I•Às ©F«ÖSš«\¾dsºŽ]|[‡•q|¤’–H}³Rb›Vl{`¯ s]àˆjoG}™bƒ›E}žLmW´·J~½Pkœ:À—‡šë®‘–d­›[r¼cw“_z§V„‡=g²OˆŽHž¬ouF‘˜Z’¿hp°lu…FïÞ¢Àÿ¯Ûó£Àð{‰²gƒ—qÁ“L§üe‰¶=|‹Q–]€¸l ¨L‹Ø~…±Kˆ’G¾Ív‡Ã]†¥S|‘S}D„›Rbœ8l‰H\ƒ@p„>‹“Sy¯XŸÈk£¤€ŸÁj©KkŽJp™Kn‘TiV€“L­[ƒŸeyšH¡§fÔàë®î§š±c|•_”®v‡¥e±vŽ“M|”NŒ±|…«ot™N€IŸÉk–Ãk¤³f´Ðq…´fšV˜¢m¡Ú—}•Uz¢Sr”Js”cNn“NmŸ_‚¥nšËk®Ó†¦Ð[r£GW€6hŽEk‰Bh…O}¨MgŠI_Fk‹Oz¢¯”Ä•o˜mi‹O‚§]„­Yš²“µØŒn•LY…>i“OpZ}¤f‚¦[‰­}“´k–½]{ [p@gEg—\ˆ²Usj—ºj¦^d`}©Ps•WrbtœZu“FfU›f”°ex•oˆ¡ft‹P_‚Xw–eˆ§esœdq“Wm—fm›esšiw™m€žpu“WšW{™[„¢jƒžv†¹™šÇ{ušTt˜T~–Yƒ§fЦ`“°^Šš_zšdx‹c’ k•³d”¯Zl‚I[sRuVnƒOv›s¨Îˆ¤Çp±m–¯`“¸o„©†‰¯|†¦fƒ—Zo„Ww‘JgEo‰WŒ£m³cbRV~Y\i@XzDgu>f‚CmxK}…Ma‚Xk~S„}IqVq“{q›my–ho’aW[[m]oh5_|?mpEn‚DiMm}\jƒLg„Jo€UwŽV€‹U‰“`tŽ_t‰_m‹X_€U‹dLoŸFQajrfq‡CL”W2jH;B;ZJ vk$r}Ay‰If£c‡†`‡Ig do‚Rp…IŠ€O„Ÿ`J•rVq_{u?T™Ry}x…C•–V‡‘Mƒ“Um[XŒ\WoWkZDmuIzˆfjŠY~W™”Ww±W}£}†„P¢›K¦¥}Œ·m°{aŽd_qO]†_IzaXf6Ao8xcKe‘Do‹C¢G­¼n¯Î|…Ï›ŒºŸa¯w†kq›`{ŒhyŸX‡’P„ Lu¸rqŠoqŽ^œš_x²mŠj›´dŸÁh˜¾oz±f¿…a{ÄqW…`afBqtUKO\cNœn7•Æ6“¾tq¶w˜}‹´NuªS[_gzIŠƒK~¯¢¥™§šj¼‡Ž…nˆ°d›_¿R³ªf­²~ŠÉŒ¬œTUÍv[h>©}2ǤP ºb©¬o²Êu©°ftÂx| žƒ™UÞ¥_•ý–½©|¡Ô~–Á‹¢§±h ¶T™ÎF…Î~q“|—“`‘d¹YbŠR„Šp§¹‹_ЂUv[{f+w”Aw•XusLŠŠ5|¥D‘¡ahšVÞ†D¿ûec¹SŽk+‘¢>¼U…ºsŒœh‡¤wzcy˜C˜‡X€ž\mš\‡sL—v‡¨P’ªa—¹]^šw}~3ažTs‚=™•Gy±Py•_ƒƒ6|ªM~‚RŸ¼k©|¥±OtÙn˜6ƒ@T˜Yhh*ú³nwÿw‰»@¿¡l“ÿ}SoŽ`u–hyœXy’?‘Ÿm”›Oš½l“¦w}¼e˜™Wm¬u›_n—Doƒ?‡›T¨»d{žS” jv˜[cƒQ{‰=­ŠU–÷º•ˆ<¸¬Kz£CŠ=‚¡Km¨]YpR£†QžÉKŽr±£@§ªYÁN†ŠW­a‚£Bcƒ^w›J²¦rx¤q~™Vk išUØÐU»Ù{ˆÍ¦”´zެБ±N¼ªL´×q­Î©od¸ªHx®yŽ—b•FqR¯À`¥Ûm¡}ŒÖQ—Lr‰Iˆ›^ˆ©_—»Cx£WbHx?ŽI—’sÃà‚ÑÎ|–¯w†´e²` ¾k¬JRzE_nl¿–w·õ°a¾¯UÙïs‚»iŠŽCŠ‘;´ÀdyžW~”c«·oŽ‘Qy¦^Š”Wƒ¦c‘­evs¬¬v­Ûƒv¨x•³“¹S„¹u…¸m—RØåx§JŠ–b}—K|–L‚£\›¬ƒe—mf€Ed8~ªV{^ƒŽcœÖ‡¤³ƒ¢Ä~„²ØX€p› ¢Ïê¥åþ×çÿŽÁòÓäÿŸx¸Tu[žq‡±m–ÂrŠ¡q Î¦sz­Oœºv¯æ…„·i{£ZlˆW’¬g‡µHs¡[®i“É~h‚=}—S”ÆX†°`m”O‰¥x‹¥fiŠQuGv•Y°cn“Dd=‹žR…nš®»×y•Ác‰™c‚¤N—Á Éô´¡Ý«{ Ðr—Åb‘¹q•­l¤f«j‡¯Y”º[t˜Sb†>mXu’?l8v–b ¿bfI…Ÿj±j€£ke‰H[ƒNiŒAs•Pa> ]l‰BTw4^€?…¤Sy¨d³x•¿f¯e—®fŒ©\u”rv\a‰8]?l‹Tˆ¤OuŸe¨µc‰«[y¡c‡µ]wœOj“L¥Éaš¾qˆ±_}mŒ²vsšT^ŽTy¬t°Yˆ®^…¢QmEn…W„ŽvϾdrŽTj†Sn…Ol†RlŒ^‚šOhŽQe†Nh˜MrNY†Tn’i‹¶b‹¨Wq”Zl—`}›]t¤m²~…¬gn–Qq“T‚¨j™ÈjŽ¢W†¢j—¼o¢ÂfŸ¶a—¹dªÉh¦Åj¤¿VŸQy˜\~žU„¥}ž¸‘ŸÀ{¤Ì†­Êf‡¦g„ªcЍ_¤Zo„Hk‚Hh…P[xRbUv l’·]ipLcPZsI]~DjzAg9l|KoM\Ujw[q€HmŽM{†W€”]s‘`f”cf‚_njI€p8k‘F^ƒQbuN]iNdtHj}D_€H`vOmwK}vGƒ~M|~T†[ƒOƒ‡Q›ƒMy¡Tf’t[wW_x;N‚QIpCMY'wY"y‚*`‹Nm‚]}†C—–P¯]v§u}”dd˜R‡~L’§Nd¥€}yUb™?LzVxdNj“.‚XtUzŒhƒya_‹__wOn_2Xn8[kJQnB€dC­L“³sˆ«|£Z’–Xt˜q‰’hˆ°m\¯uRiJZiMuq8d‘8W‚=uœtM‰ÆAœpnÌ~j[„„`êsýUm§I}c¢¢W‚¯v|žK¶˜Ui»gŠŠ(l©E–o”ÆZ•¹‡”Ù©“x{D€ƒX‚¨YL›ÎNz®[h¨fz†Pƒ¤iŠ«`‰¬Fy’et£W}V¢±]s¸PuŠCu€Hœ™V¬Ø[gG£‹U›Ã€µ‚HÍÙq‘ËŠh}J–‹gaœFm‡-©Æ=ÝãÿÿØÊÿˆ¹ÿ‹ª×•|žnw¦mzgcx0‹œJ¹Ó‚|•UxŸFŒ¥V†¡FÏ™`òÿ£ˆåˆx›Lv©k¸Ä`çëj•aºÇX¢»†”Õb{[„³e‹“IÄT‹´Š˜¯_˜°l¬ÎY«Üf–¿R€°ažXh“Hj‰=„œDcŽ;£¡:£y¸Ù›Äo‡¥`~›K ¨}†v[~,q~1£°V¿ºp°çm¶Ä¡ÈÊ®§éJ£¿K’¬T›¦lŠB—¾XŽ·T½Ä~Ôe`˜KŠTˆžV´×t¡Ñ^ÉØŽ•¹oƒµbœÅn„½c‹ªN¢ÀY›¿’|¸U˜¬W”œMm™K„ WvˆTt©R_vYrMy£j…¯VwX’¬oš¼lm˜Qb“Muž_€¸bm”`k—pqœb‚©Vt¤[ƒ´ªàЧºSu£dƒ­v…¼„ Âv¤Ærš¸mºy²q‰¦Tz˜d‰ lœ¯wš¢w~œšÁŽ©Ên™³j‰­^Šªe°]¨QwœY„ Xr’RwšVu˜e{¨Zr|Hl€I[{LRwMXlAXvA]sFzhMl”O„\~B[“YVsYlwJ‰}RržZd_kvF_zAt}D^‰Y\tReeCrw8[|FSwE[iE^q@ph7vr<yK€•X¥~Uf£Tv„gw~ShˆhpyV|†CQœJdlMa|0v;c‘DN‡Z]lNij7‹zDu¨eŽpžb{­ešnŽ¢L|£}ƒ˜^z®Yd‰Zn†Ag„8`€Y||Jx`žŽUвc_§nsJŒEp’TW…Pc?Lq–^n™|—™g†¦]n£j‡”[‰¨P†¨nfŸTowMiŽ]•?}ZÉŸ:~Íh¤žw˜Ñ\gÁ[‡7e•PSc}hW™¡^‡¶fs—t¨šF’¾fÁ£a{Ä^†‹[c–CˆsW±£Bo¬—hPdL›V‡¬cš¢~ƒ¯`“”_z¦D—•MמR¶¯S¤­eµÄŸ¼»v…¼“„”]v†RouK‘hQ•ªQ¬‡BЭj¬ô¢ÕÍVÚ{ š€“Ç„ŠÂ……¬Zp’Q”—@²uj¥d‰K·»D­å“™Þ£oºZuP‰T°œV¤ÑipŽTt‚W|\’ªgË–bˆåqŽqff³€rl6¬y‰M˜@}”Pg}Ajƒ6£”>‰Êna€tŽ.w›d“ Iˆ¦S°ªf¾ßr”°k—­elÑ4ˆ‚8ž»qfš™g¦[yLešJ}„[¢ºo¿lh¯rOZ H‘–>‡µ€›ªLœÓ|ͼyƒá|R‘Q…~N§S¤Å—ÐænaÄ€‡D§Ít ¯cšB{šT…¡Yv¦F‚ŸY¤Å y¦Syu@}’YŠ¢kœ¤Zž¹Z²“b” P߯…˜ÅŽ›Îj‰°U’«Nˆ—>¬~•¾s‰£„’¸’¾q€šW”‘`ÒºVìÍN§ØOŒ­\`}g²µ…•³†¿ƒ‹½n¥½‚¡Ä£~°ŒmXz”Ov’n†•ltš^¦Ko«rž¤p~¯a‚Ÿd–›gŽêy“€d«V³Ÿczž`«\Œµt‰»ZnA… b¢QišC|ƒQˆ¤a»¶Ž§Îp¸Ó¬ŸÀj£Ôpçø|µçlËg”¸e•ºgÊ€­Óy„»“©^¦«x‘¶y~¦u™–a¼_o¡dl¡ˆv—z­¸»ºÑ›„ÎdŸ®E§Ãg•±r£Â~µÅ™–Án“¼_”¬”¿tr“~v^wœzn˜Tp†S—¬shŒSs€Cg‡A[sAx’Fl‰V‡ ]‹¹uoŠW•ºb¶{ºrr¢gy¶£Êò–ÀЯ¢Ú€Íëšy pµÏW}«m£°i“µhrhx¥RužN\r;W‡`hŒ`rbt¡}¢²å¿sÿÿ¾ÿÿÿÿÿÿÿÿ“qcvY–±b¨Ôj„¸^cˆ;kXx¢me…?b…Pi„N}’f_‚CRw8Xut‹WƒŽfq£^]“tpwj…–R‹™^™ `”²fŠ®pƒ®cp˜Xc“`•wKŒ¶R¡n§dv¼€”o’©V°vx´}ƒ‰T`Ž]lwN•‡\r¯Z|—aª]´·iŒËn©§o‡Àkl˜pqŒNt…T†Ž@`£[yŽ_©›SpÙSW•s[r=^„BˆRŒœWl¹lT™mZyhp{R_€¤Pd™ekŒ2gˆPYˆPwp]•‘]š±lp®qjŒj[Bso@dŒU£Š@‹¾„»¥{Šàm~¥’kœRj~[b€Fn{9†‘Uk¨fkƒnp‹Jrm–—W¯«„…–„n|OÙpL…ÄBx•²jDrt=Š5ž•uÔÏ[ü…Š‹i‚§Xg¤X©…Gƒ‘`ʼnJœ»v{¬r³œF‘©W‚”WžzV¼¦KÀìt¾Û‘ŸÐv··Z¡Òwp±~¿uI²Æx¡³…«Ê›ŠÈw˜¢a{«\µ›J›¿rÁ¶o¡ä¬Ž`ª´vµŒ£’@™L¹¯MÚÖsܘyŽO”>ƱP¡Ôed¢hvt)£M™±c¡²N{a~•H_ŸJlu6fˆ7w¨*mt|”–JÎÃ[òY—£Q¡°R«S‰È©lœxkyYs¨gu]‹…q‰¡km^ž‰C‡Í`˜9oŽWt‘cŠZe™Tr…Jv®K—‹Hž˜sÌxˆ´~•¿šx›Ww¦>ŸO“ÁN\§ockH‘t:¹ä©„˜wº®jžâi}¶v}Œ]z˜cl”T‘•KMžUgo8ƒ‡?¡œiŸ£g«‘c¯¹n³®už Z•°`žQœ¶_z¾ˆš{‡¼‘t‚_”iû°ƒÿÿÿÿwÿÿÇÿÿõÿÿ¹˜×V·Ôf¯æi‹œL‹ÀjhžaŠ›Rƒ›xvŽLaŒN’”]n—U¡›rl¢kx _„—U¼Yœ–}¹qœ¹^o£mc‡8k…>š±fu½cUeCˆ‡_ŽªV¥UxÊaq…DhA‡u¯¸pŒÀc§`˜¬kƒ±~™ t´¿ŽªÛ‰›Èa³Åe~¹z£¥j’È{wžetŽc€§\™©[Š«a YfŸN[}2€•P|¦upžI§¾‡˜¸c‘±b”¼u‹Á{̉©uŸÊmÑn•±h |nO…šM‚®P¹M”©S‡¹]¾G’žDq„=VtBs‚F‰œV—U¤Ðv¡Ãa¬ÛqÀbg™k³´ŽƒËguŒRƒµƒi_‡uc“Ks‹Yˆ«’¹{Ÿm’Áz†¥`€–s—¶[«>m”H‰¶L˜¤R{£Ql˜VÀÆ}ÿôÿÿÿÿÿÿÿÿÿús•TRoUdŠRŠªt¶Üd|¨Mm•EtJe‚DaƒGpƒ?vŒX¢P~ž?~KuŠX‡¢Uv”Jc>ršSn†MlŒP„”LnaŒ»mkgвq—Èw®`~“x£v—¡o–­J…—T|`r’V€’T{—f“½]z¤@nŠKlWvRg‚ViŠId?`wQ¨·yu”\…¢KZ@}•Dq’YcˆW§Ðw…²d‚œ‹«Ž“ºm€¦^›KaŒLœZ‹®HhƒIcˆSe‹Vp–a†¡Y‘´XƒšMj‘k¡Â~‡¥cy¡c‚¨Jc…Dƒ§r•ÀXs¨Wj_g‰m‹Â­Þ€œÃOi`z›Vz–Ox’LvY•±nš¤^”¥InŽSx]i‹Mi†Q`ŠWy¤X} Um‹AY‚TlŒXsSaA`†MwPb„Tx›i{šeƒ­\r•j|Ÿp†¨WœNŽ jަiªy“¥byƒ]j€D`ƒT|¤eŠ¥j‰©fw›nžt|m¢i~›]‰˜c‡¥jŠŸh“^u’et—n‚­o“§V{™Kw”RJ];Y[UiDZe/nh,b;[~WTjcTmEYf:Nl8V^=jj1[{CVnL[gA^u:lq<ƒrAl‡EhŽJ‹ƒX†•P|–g}€o|‹Wˆ‚_g“g~‚dŠ’[^¥kXshoeKn~GT‡V]qX`n7xi>s‡E_~Z`zWSsO`mH€x7œAª¦eš¹e¦»všÀ{ƒ¯os u“‹Rˆ¬]›s™£gƒ½{§ˆƒªkž¢€|¹„vim‡^oL‘‡O„¥T~˜s˜‹I»Ÿb‰Ò™£ƒ“µe{´ƒibr‰Tl„JaŒUšR—Å`ƒÇvt r‘@yŸQ‡ŸEj¤^Z‰_nsDs~L~z5{Pp’EkŠP‘–F^¥_^}B€-j¢T‰‹X„šX¤”]®£J‹ºez£[™Nm§dloxŠ[œmˆšh¢œ_¢·q¤¯dwÄXc–Hm{:‚ˆ1r“U¤C¬§jÒ¥†¨Éiá«Z¢Þc³Œj¿°QŸ£\—\¹“GÄÇn“â«y„twRZHx@‡ŒP³x?’Ø~´vˆ˜=¹–—…°`¬ŠRàã{³ÿÉ©œŸôÉ•ÿÀ£±´ÆqÇÜa«ö€Ò¹p~âxa¦l¤ŠU†ÓiV³Qymi”‘f¼|yº“hk†€[™Jš8¤°h°Âp¯Ã¤·{o·XŸP¬´€k¸x}y8o„4é”N§ÿ§˜Êl»T–‹nuª7iœ8m|-Pz…H‘¢Nw®VWž`‚fLoÛqp§Lb‚Jx‚?˜ Vy¼^y°.¶§1Ê~n°ZƇGméŽ`„CdˆG„ŽA¬ªA{³XcPwr0~ŽUf‘nŒ€jÊœg‡·wWxœo”ƒ`ƒ·fƒœaxœl¥U™Ùņ‰:ÿÌnÿ¹ ÿèÈÌôÚ»ƒw˶‚Šk›ªl c†˜\«Ùxk¦tlkRfvHkŒT\…S]„C‡š?|±Go»c‡O‡Ín‰ŸR t¿¿]s®jfŽfg™Ž>–ÄExœlªx×¥B¦çc§»o‹«J§¹\y¯GmŒH¥ˆW°âr™´‡’ `ÀÌi–ÝtަK‹J­ÕžÊéj‡¯™“Ãk† R´Ø`›ÃQ†¬J{ªTvyXr”Dˆ¡RgœL¨Ty§kz¬acI…œk­V‡¿v‹³lŒÀrŽºY“Íop²l^{O}‹r‰©Y¤×e¼u™Ó|‘´n¦xi‘ZtžfuœIµ³€ˆ¦O|žJŽŠJ‘‚~ž®Šg W~‹Us’c`’D{–x[‚A¢eÁaŠ®L“ªl”§b`‚C¬Ðo~©hx™Y’gdOo–QŠ«d‹®x˜´g‰¹vy¦\š¬S›ÉV‰£˜ºÿp…Ѝ„¦®“¬ll Sg{LŒ¦P¯d”±k}¨_y•Oc‘Cv”Ej?Wt>e|Ey˜Z£dy¢TˆV†›`¦Íh~¥W‚¨Pn‰S}”Qf‹Gy [p›\|“]—©iƒ˜_†¦`Çåp˜¯u”k¦`j‰E^}KgXv™bp’n•©pˆpu–MUz@bƒK`pUˆ›Ab|<[rNz ]~žWW}:PvP¢clAe”Uo“j^|hޱ[˜¶t¦Åo‰²Nd…OjvÆâ’œÂcbŠ<]Ui=VtJangŽU\~VWqVclB^sBjzAd=\t:P|HPcA]h:_m9osD—xEˆ§Mz¤i‹Ž_—”T‘dxˆdZ†\blYVoNupZ‚ŽHc£pTrn`iCau@]{KbsOukE©l@r¯LtŽt‚€MVK|qLiŠ1xFŒŒ]ªªf—Ä{¹|‰dg—s]‚`gqM…\’›_„¿}¥vš—hž°p¹cŠ£x]rœU{›S—•Pª¨g’¸e|¨gm ~†z”¢Vs²|R€xehMi||žWƒ¢R°ŽxÆßoðÿ‘êÿ¡”Ép˜¹t|¬Ez›@t©e€ egši’Ÿ‰´y®¿`»ÒȨƒºD„–[¨Ü€©mÁæ_Œºw“¯‹¹‘¾s¿®dÊÿ¦w xš¤eq˜ˆG§·¢|Uwcw—h««\„ÊT„ŽVlœRpŽHmH~•Rj–V…•e¨N‹¨WÊ銘ß|v Z‹§`ÀNgpA€šKhŽZq•ˆ^Ž^yY€ªa¦Áv€§Gˆ¥«‹°|…‹a²½‡Ž»x—­oºÉ]®Éd…¡Zt˜Gs‘AŽ¡\oŸ?kŽ@r†[ƒ£`}‘Eu§kƒ`”ªs¦Áv†¼^š«h‘À\\~;tMu•\¢ÀtvfŽ˜\Нf¨Âƒ‡¾NŽ¡r©Ï£¸CxšVŸ¸k…¬PmŠL’¶]q—piˆN¤U·À]‡²Omš>~‘D†žFv”Mr™`w˜Vœ\–ºt€¢_ž·…œËpv¦TvQ‚¢XtŸEr£KfˆIiQuZ™_lcŸtma„¤^c…[s›X€°Du˜cr—LX?Bf8TnPXxNjƒEp“@f„P~™RX~c„Ov |¿×žœÔ‡~¡Mb†?f…q½È¸Óy‚£FmHg„Xd„JYy4Nq:]yFb‚On€H]C\K\K\€]p’d}§q”»mƒ¯Xk–Qk’Ns”c€ŸUg”Vk’^^?Sw`„¬`„£S€^Чq‘¸w‚¡U†Ÿgž´`‘­Ok~XyQnV|œarAh‚N]}Om’^{§\~›D\‡GnŒFdˆWp’^ޝeŽœB]‚Jt™U~¥`ƒ®ƒ®Î‚œ¯R‰¢Vƒ^‚¢c‰š_xkˆ²u­ÆV¦Ko‰Rc~]|Ÿn†¢`‚‘Yr‰Mt—Ij‡]ƒ£_{“Jf‡KfŒ^^fFmnBnuGS…JIjMLU=]c4ag@fkEkxIjyH\€S]|Gk}JuˆKm—U\„dVrXcvHmzIkJXŽKKpT[iMMa;Pi8]d8nr;€H™S‘¤ot­n”„f¤ W³h}‹jpzVu?•“Arž\pŽely\emJgcDVB\lC}gF°nA“¾U®“ªšTb¿f‰‚n|™B–“]x±Se•an†c[‡khjHdiKjO‘y:Ž™K›˜^’¾hƒ¨r_ŸnŒµs¯•‹ \›•Sk»[hŽl‡…Vl£Yo“zj’eX‰L{pIl‹W}†f‡CDyW™W™]y¢Vp—m€ˆH€¡Hš—W„¯c„_¢™^l»^ L³gм…ˆ®…mµƒv˜¢qš·ic¬jWYbn6‹<âºc˜ûx ´±Ò²MŠí”Ö¨yºíW”Ýv£œfs¤M†Œy‡§y—°l–ŸYt¸T]’Eb5Fy0Ãb ßÀc¬ä¯±w§ÏZ‰GV‡N‚nFʘM—éc•žÀ”@Þçx¸È‘“lœK’¡k‘›`“»bФ}w¦N‚‹I„œX‚ cr”|˜W«¡jAÄN`a;Yi0am;sR{dj fz†bh”E†„MoRŒ‘3m«tsƒM›¦OŒ°]˜±K”¡^§›@¿Y‘Œh€¯Rlªl„™KŒ’NœµG{®T¥Š\©Ã‡ˆ½]›†_ §{u¢ˆò±„ÆÑv©å†›¹Žžw¾âM§Ò_v¡Iœve’XmmnwZàªPÿÿÙïÿá£â¤ˆ¯FµÉD¹ÌYÍwþÊ[Øÿ–øÿy_ø•IoI]n.r„Co›R€WhšYqsI‡sœ¥P{º1š¡I¼ÀŒu¼Jm•9j~Dp|3ª>a’Y‡‰=‚¦i¸¬n£¯u_¬R£Ž]€µ_„Ž:w”>‚Ž>Š´^h‹nE¢¬f½Àc Á‚‚¦fzzZŽRv¨?c{+ˆ„;…µ’brAˆŽ3a†J¡£S€£rݳ\´ÿ~‹º|PƒLdm[|O€}Z‹ž[’x0€Š°•PzM‰Š9«Q¨›]¹Ñ]Øñ}Êÿr¹øÏÌËäÿçÂìºy¹]…™W‚±Ur‘Z€¥Fw”C¤¿S„¸^€©]»Ã‚Á‡¬~z~^Ÿ  ”°H®Å‹·f¹åz²æK­Óx›×±ÈŽ”Ë[n‹=k™<‚€I¨À_«Çh“½N«×]³®DÖü…Àù`Åõ\{³[Œ¼F’¦PªÑmÄÜ_˜ÀM½oÛá–Áÿ‹Òy`rQ‹¸]h{I–·§j™Sr„O¿e’Ù=ƒ¥S‘­j€±_ƒ’Qz³lt}p”®k¯[lxKo`{œ™Š™¨}z i¥ÅM†£`|•n†—`y–P}—[i‡R¥ºZœ´Qu‹kš¶€·èyvœk}¡n‘»[™Ä\x¬X¢kˆ·WhƒI¶k‹«rq•Mb~G~«vj—Hm‚Lާ‚“¸m‘¯l™ÊdfŠE{‡Iv‘b~ŒI„™Kf“8`…Oc‰]‚›N_ˆBp‹LZ€TtŽSo\¡q–®`Œ°Rm–Wz’Zn™UdBSx?]|HlŠYcHWw6h{S©¼‚ªÃc£a‹©gh‹g}˜hw˜M`9c;ZwB_DxYlƒQ˜j¦Àkf4bŠkªŽr‘@l†e{“Ll‚A]z3C_`pCcuF[€NtŽHWwKaƒ_l•iƒœbv¡`sQmU|¤Wk›Of“Oi‰Pj”AdŠR~ WlŠUŸRs“h‡­q—²i‹£q•³as™\‡”\‡žR“Vz–UkŠU}œUmƒPh…Tl–b¡Ec…E\ƒLpŽX—j”½u†œKnL³l—ºj†¢€—Á|Œ°o˜´jªe“²i’£Xpi‚©‚´ÎlŒ£Us…Kk~ZoŽh… [l†Jm„IqŽPi‰Wt’Zl…Nq“b‹­pfwAguFiqNT~Q\bZGg>Qa8W^0NhDcbCfyEa~QSŠWciMm|F[S_vWT|ZXpJqv>k‹BUŽ]FyYneE`2OoKl]:sp3czLiƒLƒ…Ut¡`ƒ‘hŠŸXy¥x†m‹M«•KrÆ]g‹~}mZorD‹mJvSg~J•tG¨zA¶~E¶œX® …”jr¢stm—‘Hš¬]n¿tH†qX`Ixi7b}C`d?nuA˜‹<–¦WŠ¥mt¥on–kq†[‚~L}žc¨’p— b‘£kqµrx‘pp‹@G•V…cV^”CZx_uA”“>b¦Y™{KŒ±Z‹­u–£e†¥k„œ]Ÿ]§¹YtÌa†s bŽSŽœW†¢j¬šZ®ÐoÄÏŠÝŠ¦­p¼©`˜Ëh•¯`‡½q}£`¬–BÿÏEÜÿgï®”užÄ¥O}Ҩ΄všÞj¸²¹Ã[‡¿}u›]”‚PŒS‰¥j›¯‡Q®LukQa‰H€x?Ç‘n«×†~¶¬˜˜a¦»tv·tZ‚G‹sOŬr£ÐpÆ¡bÑÄf]Ò³zo‰™_³Ž^ÍÙzÿ“ì­‰…ðÆ›NÈßS݈g“K‘‡>e½DJoeOX({p+©“HÒÜs^ÅZM]{FZŠHl4v‡pQŒ^klHS~E_^3†‚~vžzƒ™fuŸ|¸™MƒÌZªp[Y}1¡»^]¾uzR™¹Tq¤p^ˆX^kcmtK{{CMˆ]‰eO±ËŸcª§ƒ>¯æ«u¹š—§dƒÆF~“KŒŸ;ä§Löÿ»ÿÿÊÖÿû`£c_ž…‘zÊ ¦‰|ÿÿ’ÿÿÿ®ÿûš¦‚âFdKc“MjuHAr3’a(t¾V_N]}DVƒZƒn9±²‡|½h•\{¢3mx, cZHtx,•—N¦«yŒ¢²Œ\ÒÚkqÂy œTq«P—–<~®d‰™F¼¢;¬îg¹¨\ÈÛvk®l°d§¶‡ØßTvÐ7l„H–`˜ºT_Uer5•XÀÕtv‡m§¢™Š½h…‡S¬ë:ÿÿ]ÿÿ³Çÿ—q·QbpC‹‘Tw‘TogWt”Yž‘Lˆ¦~™{k›•†—f›»tÇÅÁ”Í¡_|AhrBuOyŒL_Lsˆ3¥Ÿnœ¸~™½c‘¡Z}–`tƒ@x•BŽ•xž[c{Ož¢f­»€˜Âh‘ÀŒˆ²_¯žÁ}v­EŠŒBظZ˜Î£¥™{ÿÿîªØf¨âİԫ°Ò«—À›r”b–¿p‘¡YÒÞÓÿ½¨È›‰¹˜”¿{’É£h›M©£^°ï„•¯U¾Ð‡ÎU‡¹T}žiy j|•S‡ža™È_™»g²ÃPœÎUž¸|´Ëƒ›¼d—ÏH{€GŠˆcw–Vƒ²d–°]ž¯f—§l‡¡t|C•¤J´­n€¡c~g¢³uÎü¨±æ‹¦Ãn{œqŽ·i‰ke]m‘ka‚>r’_Ž«a\…2qA\ˆU€ŸZpQy£[r£Xy i°c“²EaƒJn‹Jn—P’a} Sm”I|—dЍifŠ?o‘Ds‹Bi™EZ}ApXf“h~ \t™QhMv˜Te‘Cg~Fl•eƒMgƒDf†Fg‰n—±v|’?_‚M{“lw–IbyV`y=Hh:Kf+Ro+Ll0Lt7UuO¢oŸÈ``WOjLToHpŒTb…\`ak‚\f{PkzRb‚Jl~TtK‹Iˆ‰P‡Rše‹˜iqˆH[wTb|Ya‚Ym‹Xx›Rm‘Yy e„£e€¢Xl™kŠ·i‘µ[y§Pt•[wœ^‘­oµv›­biƒRb…Jp„Wƒ›m|‰Oc‚QrVo‹b§] M_zFl˜vÐÿ¿áOe”g™³c{n¬¿z¢]~—e‡©p†¨ao›^m‡k‚¯}¯Ës¡Êw¸n›¤^˜_‚£xš½j‰—OoŠPr‡Xx‘fuŠMiŠJpˆFhPqLbzDVy]tyŸÀ{V~J\pTTkKPnOc`H\r8RdAQg9Fe5XQg’\u„Ww‘_tY¢~J‹§OUµxeirla:gqB§wHÆyBÛŠVÒŽS»~[ÙoYüŽ]‘®ˆwƒ]”ufr]|ƒKq˜U_Ÿ|NuahdCiu,}?‰œHŒ¤XǨT‘˜_i•qrŠkf‡ZryLƒŠDw¥VyŽeu™nlta^ˆg}vVƒ‹F^¡fYsMjz=ƒ†K›’9…¼aq n‚Š]€•Jq”k‡V†žlo³c“U­¬gœÅŸÀ‡¢po§W‹‰Q“œUŒ§^´¡cÆÐ†–à›lµš¸XÈÏx–ë~Ž®v•¢b®dÀ¢V‡åšJ…Ÿ‡SX‰‘7¥q”šSÞ¡WÈб‘­Zk­f`„i€dL{¢Dm‹Wm‹M`~apf8`:l}F³D«Ç›Á~¿¿k{Õb_ІL|G­w:ËÓ]°ìŸ¡º{²h`˜ƒw‰F°¥<¡ËNÃÙšµñÊrʆ‰•_¬=äåb£é˜w®ea—UmƒXq€BgŽ;v=³C«èyìÐ’Ìÿv^ÈšVsBuw ZŽ^dqJb~:M}8Ig;d{œˆH¸ÜSÀ¹]Úÿf‘ÿ¹¢ymŠmf…7q<‘žn†Çnb•y†to‰Â>”•A˜ÎBY—ZTnEam0Ò˜C¨ÿ—ˆ°|Á³`¢îЦÍUwÍv”‡VƒÄièkÖ뾡ê×|¤Ç~šmFx;‹u$W¥`[ƒNÂ]èëÙ±ÿú`£…yŽ[e•B[ƒAS€PFh4r\+…›kl”8bmP¢9ž°Xo™vpš<œ¡R{·_|iE¥–AÇa’«x•ªYšÁ­Kš³Jž·”“Æ~ާYl•Fy—a€£j§¦pŽ¢_­±~v¿Š¯±k¢µs˜Æf®h‘³Ìq¯†x@}¡Kg‡Rx:ŒCz©A‘yZv˜G—{:œÏm•_ÿÂŒÿÿÿñÿÿÝÿÙÆú«—±`„­To[£¯@‹±[{‹muxZHyo`t¤po}]†Ža¥ÜzlD‡ÎU• Q‚©fyª^{…H¥¶` yz£l‘³R·c¤±‚¿ažœf~¶X—”S”Ž]¯³“˜Ér•¨u™¤‚w´f‘ªqr£i› p­ª„ªƒV„RNw6ksTf—TX‚O_zUy¨ƒ]~l‰©uq•g—«ˆ´Ô°k®mr£Nw¨vw™^ŠÁt­~}·ªÁu¹Ó’x¤^’¸pf‘O¡²:˜ËN–ÅPŠ»t¡^ªuš¿}~¥{„•|“Âj†¡V•˜@ƒ±[ƒ™d˜¿d§¶ešË–~p¦ºj¢ªb‘µjŽ›cdVyž^•ª…ŽÀ™‘¹rŽa|–N«cq“@a‚J®V[€FŒ§^rŸU•H`y=m“=|c}›Gm“DsœOb‡X¤µfyžWm’G^t=n@rŒRy‘Bh‘]˜¼U_CeƒFa„GfŽJ]ƒ8bƒ?YƒB_~En‘Nm…Mxš^g‚Hb‘CyŽInˆTrHh~6TnN~¢UlHk‰cq”ZZIh„TcAUlFdzQ_‰;gzC`wAzŒTmŠVh‹Sk†\u†NsHezZˆ™Mg„@Vr;Xo0Mc8]l=ZrY4QhK_{Ff|VuWmnQnoBssLteuƒt‰ž{œ§o¥s·¸‘Ó¥·“W™‡QzsU‚lÏ®vÈ¿uŸÀilŽazœax—Z|˜c|©nxŸe‡°l•³iš­}¥Ð’©¿tw’J\wAuŒRhU{”auˆLu’OsRqXv“ew•\yˆRt¯–ÞÿÁÝÿ‚®Ðˆ¶ÖŠ«µy¿yŒ®cub‚¡]yœRs˜Ru‚]{˜ ÅžÃ{–¡n’WrŠUzšgƒ¯k†šJh“OsUu”U¤R¨V†¥Y„¨Xx‘Iev>Y€\z¢xˆ³sdŠG\†ZQqLL^G]b4[s:YqBOuCOfA\^>]s3_mFTgCNoFW]8Sg;JrDV[GNa=R[5mf=_~Kw}cxX}kq™blŠg„Js‰L\˜_\{Xdd7zpD¤ŠIj£Q`e€xGržJb’r]xVpj4pr;yF”w<ƒLhlSEkSfLT|V:QzgP[c?lcVXWbr=}yLd—W_~Z~yD“= ¤WȱfÿÙƒÿž‚À}`ldP„yXoxY¦zT{¡Ia˜^p†^e‡_WoY:oJrRA‡{4QŸvul[‘•=ˆ«^¬ªb“Æ‚Ž¦…œ\l™Sk|HtBi‘VegxAzCÅ›lo¹W`uV{HyzLÅ›>£×o˸m°çƒcÖ““„‚r™S¼Š^¡ò“¸´™Ðt‹¼t½©YpÜtP‚uŽd4˜ŸHŒ¥lžšdÁ¸eÇ¡t…±p‚—`c¥‚–C¬¹]zÊXƒYq˜_oœ?Z‚Omy7f7TxežwW¢È‹¬¾s¢ k¶c¬¯@…Åm†¥Ãá¼v¨÷މÅ`ÖµFî—V¤‘LiHw|c”–fe²^^‡5tˆYfˆgyˆG—•J€°A¨›I¤Öa¥l~˜v–”f°}®‰{·WŒR~(»=¯åQ^ÈXCgL…n5l;rˆ.oŽW‘^¢¼™žÖ«©±‘Ëu®’]xÍ]`xCe„E—’[¯ªj±wdŠU‚SYSOl7bf3³¡>Ãÿ¥k±Ÿ–~GÂÛ–”÷Å“Ÿ‚y—vƒn…ÁSv•X…ªykŒ|=rªN`‡<[oEN}Fss3’¥eœ½œ²pˆ«B˜¡ˆš]†›cƒ¦[}‹U›Âmnž^™]ƒ’[v \…™O¡Åx¯È›„´xŽ™Tt’a~kJj‚@a|>rˆCmMsNp‡@tWw˜NoŽQw‰U‡ŸZ{˜KoK‰’VƒˆM†•J\v5h|AtŸO{ŸS¯Ìe„¬t€“zlŠj]sJ\s4W_)LY>aqUmvY¤|F”„N± Lµ©O×®S­ž^®“gÆœˆÆØ…³Ö’½£v•~k°j£Sxch”‚ѵÌȃ• [¢m·×l‘¼c’¶k²eˆ²wŸ¿‡¢p‡¯’¡¸cl>j†N†–WqO_T|WЍ^…¥Y“¢Z}ŽJo‰Pq’U‰®Çô¯Éø£Ãð–±ÚŸ¶Ïƒ®ÒuŠ®^ƒ¦b‡¨d€¥[¤X™\‰žn|¢ow•^u”g·fŒ²Xˆ§h‡¥dŽMlM{šZ…«i•½kªËs¦Ãiˆ¤XrŒLo‰Gt“\xiˆ¦bbŽF[…aNpPP\LX\5\n9]q9]f@inA`t?E@FVKRF:Mk7Pg:_g4OyET_IM\:IU3C^9K\4]ZGisCcz]N„`Mr[k[Jps;O”VNo_Pb6ea1tT{0_tDzM“¬V©‹jªt‰­X¤¢b­£d{ŽZv{2y‡:˜Š1ºÇl„áo™IΪ\{ÛÒh}~ƒy`c†C£t;˜£DVšc‡y,¢Ÿ`–ÇŠ£«‡ Ðš“Àyf«cS„_oy;qU}ERžgS_OŠ&zÇno~1|œ.£©>u³‡ ]…¦Us‹um¤raYƒƒWq¢g¥Ke•cm“N`0ek-X{Kiu>bŽ9QlLje5¯V±¹b‹ÙiSš_Nt/Rw7Rt(§„P…Óœa¡8ktPŠŠb²ìi†°:²[‘°o£Š‹Âƒ|ÉM‰Ž]ÞV|«^i‰X˜„A’¸p‚µfužTh~K[†Icp1T‰¬’f´P“V Ãa¡¥p²Óc˜°ZºZ|¸j}‡i†”J­Çu““n†`‘¡Fˆ°bÆ« éÿ­×ñÀÜmªVX{$y˜) ¦Wßÿ»‘Ñp……WY§caq)iŠ1ovR`–9tŽGU~?|—InQ~fq”H€‘FYBz„K`ŠN•—`ƒ¢X§`€~bµ¼‚|¹–jxW„ŠNi„@m}L^JfoKTr.l{39´â¹oªWiŒ9‚Žd‰Ptž†{”dk}I}¦gjœ=fm.š¸\‡½GzšB¦¸Z¥ÃS¨J¢Ñoqžnn‚Zs˜[~’T°Õ~ŸÜdd—Wcrwh…[¢­q«¾{tŽpf€XˆŒ[ž»q‡–h^™0r’B|¥WjŽ<|{^ª™|t¸][pO¨µN°ÛV´Ð}¥h‰ BޝBu–‡’¦v…°Š¢²i„ši„ O ¶c–´r{¦H‘´n‰ªm±¸§·æm‚¥v—Ÿl—µG}£]}œ†Tt@^z@{Ž\q™Eg‚GaK‚¡m…”j¹[޹pmKg‚@jN­_†¬Ty™djŠZ}¡k{¢j¤`y•bw¦Rh‹Dn„:†¡R§RmKs•Y‘Pc‚F`xCb}Lv‡E[r\zNo‡Gt”Z{£]–[”ªW›¡X_‡\YƒIW~:^€Cr“M¢H‹ Uš­dz—LbˆL}a—¬f«[r•_oX‚›X}¡f[¬dpœ_o•Or™h–¯wÃô°Ãõ£©Îpœ¿QoRŽ™Yi…:kK‹¥O‚L•vWÆ•Z¤Ho‰N¼¨`Ú­fعiÀ®mÅ·ŠÞÄÂÁˆËÉw¢›e€—y™…r­‘…˯¬òº¶÷¸›Þ¿{Õ¡v–žr“¤s¥Æ‹»Þ‚¡Ì…ÉЇš¬vžµ®Éoƒ›M{‘`{šU}‘L}Žc|”cƒ n¶¶i‘¢e˜N„V•`¯y¥Ô’®ë›¹ç˜²Ø˜²É‡ÁmÁu”±g‚•]v•^ kŸ¶g}™Xl•Vf‰Op—`‰»¨Ö€£Öw޳]vŒJo“_ƒ¡^³}¨Í†¼ß¤Àrt†Oq“P~ŸRs—Wwb{”]QŽLJvXGlQEaDO`8]i1^q3cn8nlC]…HOtQO^FOV4Tf1Rs;Un:Kn?NbNZ^@Wm5Gk?M_PmDn`6xo(K‹>ZlNXiHzq=MH2_dcE2ww?S}^ƒeRy L`˜R„v?q™NY‰UMxwlhXe…=ƒ{9°§R`¼m`jOu4}™c¡˜R§À•ÇÈŒžÝ¿•­©~›Yª˜@³ÍhŽØ¡›¬}«ÄisÔ™‡yk”G‰W~™o§‹W¶¼dè·hÿîŒÿÿ‘»ÿ½ÑÑv€á𖍉†½t®¥>ÍÝmⳇ£€¬ˆ|¬zÚW‘ß]´´QT³Z‡p2ŽZxªM¥‘OÙÎsµ·y ®y|…_s{A¯’9‹ß_¤±l|®‹wLªž2ÉpmšF†@ë}^íÿO‡Ñ…Sƒeaq0Z€@mŠ>nGtŠw¬šp¨­ƒ€¼ŒTŽ\–j6v»\ O˜¢R—´RwÇ\qBg›4‚bU—pWi=NsOXbNT}=Jq8n_<€ŸMZŽP`7O2kw;i=hr6…zFPvTVt.ed*q¤K¥;`àlgŠOkˆ$¦ž,d¶Z{iRs»iˆ™[´¯U…«Bn•dƒ¢b„¶^Dw‘R‘œ@tªN¨Sq¨WfŽBY—.‹s2‚®P§¢h°ÀKf’:\{=Xr2†•2W‚Op€YzzH½ªw†ñŒ©—Š”ð¥s‚Rޏh¢š>š¾mŠ¥|[qVš~n»êŒ{­gƒ‡U‹§€²¡ŸsŒuz’`—AdŒGÆ»GÇÿŸÑÿ‘ÚoiŠYt=h‚1nŽ3hBrHrƒG‰}} jÄ­mÆåŽf¥SR|9yDTXt†X_xXVdIˆ@¢µ‡o}J€sKs”Wvƒ8›£K ÅV`5hhDx›Ya’y³‚{‘ßw«ÌjŠ£àðg}Á6{“Ri€@j{C_ŠIbxP†bûõš’ÛbŒY]…WcsXŠ£‚o¤Q‹E|­O]~Tw“k¡²w~§Yn‘R}šKºo¤ƒ·[p˜a‹ŽnŒŸµ·yw­hƒ£Zp‘S~›VŸGn}AŠ˜bhŽMrxT¯Ç”¿æƒx¬Pm‚[ªz¹ËŠªR‰¯g–Ë~‘±hšÒ”­¾‚…£h¼j©ro…’£v ”šµygŒ_„™[bNpSs8zBkŠP“ªPu‘>kŒAsšP‰¨kj’]¨im’Jm“Uu‰T‚|}¢s‡¢T€­[hV}˜^‘¬\t•SwŽU‘¨YÅð‘·{§XqŽYh‰N‰‘WvQv‡GxˆL€—HkˆD|„L‚Lk‚b‡¡jjyMsŽ_ƒ£]j•ASp0_|EgƒJŠŸNg‹gŸ³Z…‘_nŒIdˆHz•\žšei…N˜Pz§Xk˜gw›HvšRu¡c•­d£Éd¢ÀLj„xм’€³„„¢tª[‡£_…œY–eºä–Ñøˆ žW¨~c®Qn7Š•V¬k­§yâǘÿô†ÎÐ~ñωÒÉ’Òð·Ûÿƒ¼Û„®ÍŒÃÑ“éÌ»âª귟Ũ›Ä½’Ë´qĤ⼓ÖЭðø¹äÛ{Œ®„¼‚§{—­j“²lµa™¦Y‘eŠžiœs~›Wˆˆgš] ›]˜™h›­v®Ûˆ¶éš®Ý—¯ß§¿Úw ½p·cxšZpŒVt—]ˆ£{±Âw•«dš¼aŸ³Q}_~¯‚ÄŒ™Ãƒ³Sq‹Ri‹Voeƒ¦z«Ëƒž´gr‡Tg}Qt”]‰¢U|¢Zz¡UoQQŠ\Tm\`lDPuGh^?]r-btFbtBlqHaJnzNgxAUoHknAH|@P_?Uf7\g?im>S}>F}GB_ANZ1MY:X`1Kupµtvi‡œLƒªolŸqiwSkNl„L‹Tq‰Qg{Mw†H„`Ü”bÿ¢Yÿ¥XÿpKÿs8”ZD‹©Pu£S~Qz}Tv‰`yxRˆ‹s«˜Xº±PˆËq¡–w¶±X{ÞŒ‰†Š–Wq«^f€VfoCuyGQg‡R`ƒEbs=epAhr1^vBpjK¥€C¸Nz°]j‡W{h3†{5|‚FƒŒH›•E”¬c¡¬icºdb{Ujp8‚s4m‡A•{]¹b›Ú…s°‡‘ƒB²O¨S¦­YcÂjšue™jrŒX¢‘O‚Òq{©j•‰iœ³{T¸{SgYw{>\£Ašv>‹ŒVp§Zlua‘Œ\S³€[qsaTDrkdt.p>w”=NXÏng¼Þfª×g}˶¨7l×u“†HÀ©`¬ÿQØÎg‘ê…›¸eµ‘_¤œsž«‚–¦`ÎÅDŽð…•{…–c‚`{§_|•ds€eb{< wBº«Q²»­…Ë•s—†^W5g9\Ž4McDˆ_6x“a•~`Ìß”sñQ|<§t>”Æh‚°³u p“®}±…ѳNæÿ–“ÿ¾nc™C^€?CV?…X'f“}ŠTN”Th{/b…Tg|/Ž®/…¯Y©>gŸbl€Ck‰7‰‡Hy’I¤¶O™ÈR’mšªp\°O”,ˆÔ‚¦:XŠOtd+mCw¥„|‰8c²„pt2¡|i®`c~WJXRNk4qk3›µŠ™¹t¨Ô?ƒ¨Iht:jr0…–D{H¼¸dÐú©±å«ó‘‘­g`™Jlr2‚r9j±Adh/`pKTi3RrFat]rˆK’ƒIy¸eY€?c}`vIfq9mr:u:\‡KduTapKwqBЉA{–TjšdxT|žal›`P‡`DmZEdCcf …}&i¥=bqzsVF„‘d¡”s|”_h“_{zI‰”Yt•`u‰d|ŽS’›Sï¢_ÿ¯jÿªmÿwmÿr-ŒO?„”K’¥fy†SzwLpPuvJ‹G«‹`‡°qqž•v{€¤‘Y”À„™”ƒ“¦`’£jœœr—Q™¥W¢b[„VntIWy9MjRQ_1YR1we§ÁZ Å™ÂzeŽdlkH~u9ž~Bº«pyÏj†¤‘ˆ›n”’g…«K~›_t…\~™Q‡ŽJV¤xutY—•Z³Y…šqs•[y…sŒ‘E|[|Œd“žNz¶dzŠ[{‚;•_°c²œLµÖLêÕˆ¨úÛº†ÿvv¥|n©H[FUvIRy7V{A|q(ˆˆ@}šPs‘N–@ƒµ{—¢•­Ëw̾cꀌ±Nšžl©©e©µiÍ̆¯ßˆÊƉªÞ˜–Ïwª¸eÇÄQgÖ³‹…Q—­mrºpW“]rvG{’P|‚Rn‘Ky{Irœf^€[ca:{Ž,j‘R}˜^d‰huy8Í‹>ÂûkTЩmjRja‚,wŸ_Ca³Q_yCh‡Y’|DŽˆb¦›jGŠdu´_u™EXu>Yy2Jw.FeKc%qj)€*d~=€xX” {—Çi›¨l†·y–’E»Ô„ÛŒ„œXhƒbšM¾s¡‹¢¥Wd˜SYy/C_/nN$»Æ@b±<ˆ'ˆ¾8q°aamD~~RdxLƒšD|m\u¢:…›ar’‹ŒŒN¹Y‹«v~©Z¢¬~£Ý–{¤\q¦R„¥cl‚di‘\w‘G—œj}¦d¢šdŸ¸‚—¯¨¨‹xˆj€ŽJ̽p±ÆWk‹A£‡W¥µo†‹_sF¥ž›®·—}ªf›±£—²l·hq‘O‹ªƒtœ[vªj{˜IЦ]eTu’D©a€¶HÌê‹“ÆpЬg±Òq‡¦j”±Y‰P˜j¥v€¥Oi‡i—¥P~£Hq‘G‰œjx—Vˆ¡S®šF¯FiN®nž³\|³:azNŠ¢u°ÈžÀ€b†ewEdmHqt@m‡PeƒUdwKjySduO‚kOrŽUKdEhTEW€˜CpªciŒ\gSk‹>^zMao8‡oQy‡WsŠd^”ZlvNz€B„‡dw•g‰‡Z›V~ªSžr­Ÿf\ÃeY€ev`/cjFo\3d~+€vCžœF€Âo•Ÿƒ‰¶‡ri~Ck…>Ð{:Þ醟ñ–‚Ä i¡{l|g™wRu²k•‰c‘½bk _H‰XSk;ˆw5l¥XYŒfe^Pi|A€EˆœN~£eQˆ]^t;\q6]a*rbHfžX’zPºy…­˜©‚†¬Ž³ƒŠ›m…®zs¢^~—`{­^n¨Px‚;…x<~Oy†;G‚XkaB–m9 ¾nÿ¥Š…ízrŸjj‰O¤„8¥°b¡§oŹxêćñÿ­Çÿ£˜õ|Lª…ƒwRwMŒ‡Xq¤}¡˜]Ÿ¿F Ì|eœazˆO¥´;M¬[;j7od&~†ELzXms:tŽ8x£0Ÿ©@xÁœ[ŠwNb?{x ‚ˆVh—e•¤aR¥šRe=rk>~”R¿°BÆÒƒŒê†x~‚pªqbtj]{[Fp9rc#€ª$f˜:†-x„<‰=k€<||GÙµ\„Û`€¢hˆ£[ÅÍttÚ‚|Io¸j–Kt¶z‰R„-gªHrp8¤¥>èèWïÿÓrÅioˆ:–s€•OÈÌSâr…Fª–Ys³dp‹M’c‚£SvžcŽ­}†yr|Ȇˆ‡RÄi§jN@kt8ŠY¼?VPj>_r4[k5cs?hkKk‚BŽJg•B|zJk~9–Kº¹ºˆÆƒœ¨ZŸÂrp•H–ŒWm}Z|y<€E~›@»“g½å|»°e°õe…¬Sn…M|€C~¬M›Éeµ­ˆ~Ø]fˆO^tDczB_|Fk…J…ŽP€—p‘ÏUh‰Pr>ƒa¤lclFb„Oz€^† Q…\vt[…°hv¤…^|4œ¿Ch¥qu‚I‹³[e™lOv:_rHvˆK•¥«…žsµ¿R©ánšÅ€^Šb~™UjKo‹OXr@oŠM¬]f„E‡‘G¢œjœ°~§·L¡¤Uˆ«^‘|•ª‡…”cš¹— uƒž^ŽN~šYšZd‚Dstt¡º{‘²Ty¤Jr–X•JXŽ^t€aª¾|Úv‘¬v‡°xz—’£”x©WnŽHo˜m¤¤…¿×h‚™Zš¥Y“»dœ]€Uo…`Ž©Rx—Hm’Y¢¼oÇP…ƒSh€g}’e×çŒÛÿklœPy—d’¦ƒÆ–‡¨zg‹R_ƒDsˆJ²Éb{¡K]‰4x‰L‚ `”°da…SuŽP}u…©j§ªt‡œrz˜q]z@q‡Ex Ul’W„ _~°ky–i¸Z‡§_·jz¨VdŽZlœ^ƒ¦rŽ®V|žLdSl”k™Å„©Ðx‘±\—Ãfƒ¢qªÈÓÿËUޝ‰Ñõ ¦ã°Øš­Þuy˜OµÒt¤Íˆ½à–šÇUo{J}{QЇO‘©o­×p«vˆ­yŒ°’«Ùƒ§Éd£Ìd”¿T›¬hž¹”Œ»y~¢‰±–€£yЬWy¡T~˜lz¥l¨p¥Åjš°yœ²Œ¢»‰ »`všPi™_y j¹¶›¬… Î~¢£o©[œ™d–¼sް“©ÐŸÐï®ÊᎵڶÒ}Œ¸n ¿Ž»Øš¸Üƒ¥Èu¶[„­`~´wšÃ§Ð§Ïcp•G^…OqœhššUy v«Éq »av§]ušEtV~¤SgŽq³x™»o‡ªl†ª[~˜Sn’fs›nŠ»p‰®]~¢d†œh—±e†Y~OjWw”oSV*Tb/Vg9bkCcqEbxJllMZ†MZzTwrVmJuX|’K[›iGxbJ`?QZ3fd/ty9j|AZƒ]jgU`~E]€MWkN`o>So:SjA\f7nj0by9_O_nP`q@mxBv{>p“V\ŒfW{jQvZUwTjqNRFcsEUu0GdLZ[MHx@qhJƒŒ>ˆ•Vlšk|„is–N{“]†h V›cwµfÿ\ÿ…Hÿq0ÿVÿk7¯Q;’¨?{°}j™m_†Sf†n˜^‡P£PpžY§„^«ÌfÁׇxÛ“Y­Ofy4©•K.¦‡2@@\O%tu4hAg;ž‹nžÊa˜š]•ˆGk KŽUÀ³Q´ÄŸÅÔÑüÃd±ˆZvt§‚5‰¿sV¤_‚nuse•²V‡³^_›†W†jE|h[n9Z}#Z‡@h€3^›0[t0m|SoqHrŽ:’€AiŠP~ŠFc—OPyB\l0VnP~yEýÎRÖÿœ›ô¸H¥f@WCeZ¥ˆ?”©Y|ŒP’I‚”1“§:„£d¬Ãx]–It‡I«´NšÅV|—ˆ’ŸaŸØi~ÒkX5]n1es3Ck/qucƒ©g‚™b±ÆnŸÍl”9w…QpƒGt};‡—?“IŽ¥]¥³Dœ›bž®lŽ\m‰= Ÿ_„œ[‹™P€•R¿vŒ›^§¼y¥OŽ´P¤ªo“¯h~žLtŒJžºb¥¼Œ³du¦Q„©hžUT„b)í—E^êuqzb­ŽEóÄxÇÿ‡Úõš›í™‘¹u{§UX¢Q:kis^n“1˜…<“«Wª¡iœ§Vœ›f–¦Jošeˆ’SˆŸ>wœ]nX˜‹I×Ö—ú’¥°ot»f¨ŽY…éŸiŒXt~C˜{:zÐ<”­Sb¸Lh‡RMˆ7ab*^ˆXcxV}ˆ:‘š>˜³‚†¼”b”lMxIdY1f\9ˆ—Cn¨EDo˜LgŸCZy1Œs9›šgÿÞy¶ÿúi²¦d‚sm-Ds+”`>–³}}‡=p¤^€„z`²È£ŸÏ£ÒÒ‚Üéâ÷”ÎþZÐßX’ÿ™®Aª¨W£ _ÿÿqÃÿ¦¦¦}´›QÌÐ]„{k¦‹U~¦Gav1D|2LR gq-ˆ”=’™E|¸Xi6sC•¦?ŠªYˆ’€—›T‹¯R~¨otS†¡\œÂt‚ª[qBWxUjvP„xA„ªd¢¥Q{²`¸¤]‰¹O¤ŒQŽ›J¥£¿`žm_pR{S·amŒ@o—>”h¿ç¬zň¡?›ÀLlƒ/ÂØa—Ðgƒ·tSwC‘‡ƒ²p]‘J“Œk™©PžG‚…WƒTºÃ`¨³}Öe“iO¡°Q°l°kÏ_§¤nz´i—°_Œ¾|‡£G ²rÄ×…s²ZpšUf‰[xˆ€}ƒg–Y­ož›f¨èJxF€‰Q|“V‰§M~‹i„œf{RŠ¢IkayvQ›i®Ë‚”ܰcy®Mhy_x›]”°]˜£mÅu¹Þ”޽‚›¾±“£Œ±·y`‚XSrB…”dœ´}w”eh˜Dj‘a~“n|¬a|žX’¬b¼‰±ÍMª5šNšºk›Å^w¢?XyDr–rvŸz VƒšPrV€¨I_xY€”Tª„›¶o¦NœÆo¨Ia†GgXp™SKlnqmt“Zj†‘´ÐŠi•B\v^“¨³Ûÿ€v¡Psªj›Ã‡ÿÿ¬—ÅU_oP_v=eˆILlgy–~¨Í£Íšw«›«}¨ÀZœnŸ§`š®‡¬Ê–ƒ´esŽMu‰W–¢NoSl‰cp‹v•»‰ª–®²nrŒf~Ÿv‰³o¯pµÙ^|¥O‹µzŽÄX`‹Qz›Tw¡[¤c†·Iw•O}˜NjšSsQo‘c€¢nz‘Xw¦nˆ®p¢Ç~·Ém¤œmµÄ“¬Ï¤ºç®±É Éñ²Ñõ°©Å…œ½|аb‚°‰¨ØŒ¡Ìf“¯[}žOgŠbsŠgy—lºeuc}§j“¸ržTs™Rf•S^Œp‚§‡¤q޳µß|˜Ã[t™Y|]n‡Se‡Qk”Dp‘TwŽ`uˆXr’`†š\~žo Àx¦Æh–ŸXy‰X€™mdM[sM_lM]l=KsKTdTs[?Ž}6p’c~Šq_ŠX^z_RnFpjMrCq€Ov‰Oq‡QoŽc[t]Pz`\Y?as>opHcw9UzMcdLxq6jŠ?}{Qa•OS„cwZ9k=lzTp}LUŒK_kRY‚BKv\WfKvhRV;\xXc€6|}4}‹?t”K_–Yer[}xP€‘Dš‘tÅ~„¡‹–œ`vºbp”x€yMÿ{Xÿ‚?ÿf$ÿo+ÿj2á[8š…7š™}Žš]ŒžR–°c£Z‹W|–J€œ\›QŠ”T~ˆG‡ŠX“S” ^}Æ~˜‰~˜]¡¡Zœ½€¡§€”¬S‰g…Xš€P„“UY–”Nž¬u±°s¦°|¦‚x„Q„ˆ_± i¤Èyz¡g¦—_ŠÎeŒ®†R¢{v;ŽŸ/ž‘I€ÀopªTy“J˜“D´ŸR¢±^‚¢s—‰_|Ÿd~žm†™\ˆ²„b¸r_…3‹‡:€Å4¡¢[eÀoc~\|h*fg;ht:B€vZaDSqG]vM`ZG€oA_…ReJmtTUŒ[ymáëKží}—s†PoƒD …@Êdtžy‘ŒH¦Ì^™¾‹›¦‚¶€«¤nà×Yÿÿ}·ÿÏÇxp¬E¹·Tí„b¡UuyDn”RT‰<”ƒ(„Ç;£„]i´s‘’v¨³™^§gV]@O9tl&|~h{Ÿsf\j‘?^HaEkŒ-]j6BdWgiR\¨)¶˜2¥ô–c„yŒ<‚ŽIw@ƒ¥`dˆPj‚;Y€8f]m›•}w¯nlƒQ_~R…‡4é|<²¿k¶Ë}X¶s\aNˆ‘Z‹…E”¾_‘¿‡VzsyoœÂÄ’>¿yB^ ^o7c€AYy={0¤·~q½µ”}<ÁÊ2tÉ1§‚¥Å½ €{F­Iª¦{›{CáXœÍ†gn‰ob>ž|[ ª€¥ž†kmÀ~‹“™|•_Tz‡–f…~UµW£°pªàj¡±}p¬`©^¼¥i¼Î}‹¼p|O‡c†Š?w}CšF´½fµÿ`‚¯Bu¥Qi~0ŰX…‚Zš¨^i_Dxˆcˆ¢rT”gfs9¨ÆqfJX‰NOl9]ƒ0Uw:ee1sŒX‘^^\8]T½Ò‡À¤g«¶Uƒ¢RŒ•NlœpX{3Œ„8„µg}ŠOb„Yt‚5s‚Ry_p|P‡Ÿv—M‚v^ƒNuil‚8v£Fo‹cƒ™[¾ÕP¨O¤¢mÃçt®ßg²Ò~}®TŽ{~—™l‹®Jª¬z—atW‹®|…«‚]€‘v~¯a®gˆžm¦¯mvŽKŒ7©·7j–8Um2t„DtInZXrOšž±¹Ò¯ÜY…¦e|”jl~Y‡šq—¯]s›K~ŒBf~>“³‚rcÃÜ}¥¹{s§Tv¤UyŽV}˜bÀnw¤{ožu„–UªV¥¯pÈë_ÎPLo?“ y¸Öst¬[Op*rw[¹Öa£ØYh­fcl~ nŽhe„Nt_x•hs—Xg|V~•K{›pz \ryZm`h{>ezK‚–aŠ­`£»n™ÀkÄÖ r¦J^‹@UvGaƒIN|0B]2e{R}™a›Ë‹«Ûpƒ«T¥Ó˜ìÿ¯¡ÌW›¶i®­èûõÈíkuš5p‹Gt‹Gb‚Co’Yo’{‚¨•¨eŠ­…¤½m«ft¥c~•jvkhŒ[i‰]­bi›e]wScƒLczjœ´‘¬Ò~“³Vn–Wh‡VY~\bˆfa‚uƒµqŠ·~„¥eŠYy¨f~¦Mfžfбbs£SZ€X‰¶jp–GbPn”[r•Uh”t¨q}¦{’§c‚ˆo¯†Œ®¨Å•¾Ãª¬Ð°¿è‚޹€¤Ô¥×{£ÍˆŸÌ£©Ì†¡¿r‡®MhŠOs„To‘m¶nŒ¯mœÂpx§_s‘Up›Ux¡Vpe€™a˜e€©ƒ–¿x“Áw¥²j™R€‡Lp’O}¡Y‹¤R…_x†Tt˜f~—c„«o—µr™¿kФZw—^„¢niuS[~TUoGVfCPnEXhDna5…}8|‹Ng™jW‡g\jVhmH†tF{™Ps•ohŽfi‰[_‚jTl[SnR^eC„h3s‰Eh}MW‚PXkJif:^}CTƒ`QoFqwK{z•m…¢…¾Á–¼Ü—‚s¨ÀTÁÍ“ÏX¨µU‰¯WyœLŒ³kiI‰Nx N‹µ[‘¹c–ÊG®½‚‰µO‚£W_}”Li|<¢­‚s›Uj”TmDmjDip7ŠuE~†Nah^€dLtJh]7{u7~™g† ‚m¦}\’qZ{]ojO`…I{wQŠ|>p—SpsWY…SdcITtux5êŠ?ÌÿŠÕ★Út“o–œAsÄRP“nehYM†KgrQ{Š7‹f€œZ§rr‘l“’n¬ÄkœÅj•®mw¦ƒo“zi–e“5µ¤MÑpœ§r Z•U§9¶¶W|¿Qa“Nny:sxQ†1…ŸE¤‹dËU‘Ÿ‡Äv‡¿gyLŸv3·Éi·ZÊËcµï¢±Þ€xØ©X“cWwEVs4XuCƒ1¼§U™ÒZg¶F…ƒP«§{ŒÍOpžs~£:„¡EôÆGÔàv¹À¿ài|䘅W`¢t‡rCv“NX…Hnb9“‰AŒ¸bžd‚•œž?…žEe‘PKi?lj1x3w•Jˆ˜C^¨HzT(Ü»xЬƒžCa±HC^‡BU$pU,›=yW=†ŽS­¢:§Ì]lÈ[F^’OmXÆ´hÓŽXdKq?KSGps3ruDŸ´w~«eŸ´]´ëŠ»Ç”Äü™Àð–ôDF‹6mj&g›Lm›:v<‡”m_‰_s‡*{ŸnÈ>¶át©xÎÓ²Ýz̼;ÿ·`ÚáÚÍËbÇ´Km¯…µ•Aÿÿwäÿ¯ÝöŒ·Ö‡¿½€›Ý›’К·¦•·wWzcn‰A9W:R&Xf'ˆj™®»p {„Žv™_u¢n›CÒç—~œiUo;‡ƒ`‰‘f”ªk°Å`‰Ô?V{SVg9zE`yier>u‹H[sKcu?qu8v–LvœUq€6p‹InmXi?qnE“Ž|£ËÕw¶Æ…¢í]{‘RŸruSž4ޏDŒ¼¤Ávަk}›Onƒ@œŽ[­ÏpxÀpo{Gm†Pg‡Ad{8–]d•onY|‹jM^j>X‚9r‹B…¯qv™X¬¥TÎÌ˩ʱ Ï‡|˜K‹¾nv©RzžbaCl>jNošfx–xލ”¿~ƒ£y}š{c‹O€–l‰^‰OŽ»XŽÅ`f„B”²Rm–@ˆ›[—Ç`^~Pf}F¤^Œ¨m”´ej€;’©Sª«G§µQz˜c©w¢¯ny«a•[­Ý„p§STwAs•Q„U„¤:•ºWvxŒ›€k“[‚¥fq‰B~–eÐïŒÁÿd•ÉSŒ°bazai}\—¨i†´Vr‰hïßžÿÿ¡¬ÕLieA\kB~L‡ˆJ‹ŒMVwBšªXœËQ|”Nž®aÇu‰¬yh™GVt~H|‹Of’md{hDvDQ\fnG_zLJkHSXAhb(iq:xp3g|DauFlu;‰‘A¶St¦k„‡[†ŽS|©ap–bk‹Pi}BuzFƒ‚Dx”VÒŽYÿIÿj0ÿo$ÿ€.ÿ†>ÿh=³P1r§O‹[„¥Mn–zra_…hC_:YEjQ3v>j¦ks™o~‘S{‘Vm‰W‹•M£¶PnÄpoŒtv†P‰‘b{¶\h”jŠxP„šc¥Ÿfþêœ`̺‚{ggšSO€^h>¨Œ6‰ÖZ§±jÝx¾«gµ‚f²µTÕ˜g°‘‚@¼X‚¬_v£[Š”Oš°Te»m‚}\¦•=’¦v‘©mzŸr|—^m—UouFjC‘>x¦{w«imR¢|M¯©]»¹pxÛ™Nwrbc5¤ˆ8ξ9¶¡X]³[€ˆcï«K€ðru‹†q–IÍ9Êï|”Ö®›p´´”¡Ö’«Ï†~µ?˜M]V0o2^6|cCº¤JªÄ–c´f‘l;¼¤c«Ò‡‰½„„“\Yªb’qG¥¨d›­‰x²‹™Z_±HD“”ci–\YkLˆ{Š¢T˜«€ƒša›šK–ºªaš¼x‘™ht¸Ve„LlGj…Pk€QhNW?^tKj‘~`ŒD[wLnŽgª¢œ¯•u«S}”R†ŸiªÂÛœªP—¥Z¥Ç©èñÉùÿ ¾Z˜erŽAŒ’p¡Äcš`ÇмÇç¾¼¾wÈ®Z•IuT|‹Vn†ERr2iy}¨Èƒ¡Èc‹¨h‰¦ˆupoœHp‹En‹[p”T‹Nr›V‹°ŒÙÿ¡Áÿ„žÐ¸Ïþµ¢Ï„°×Œ²\xœd§Áy¤ÍuÌâ½âú¬»Í”¡Èv‘Äj¡Ø¡ÔÿÀ}¬k¢Sg•9Or9Io5Rr4M†dz ˆ±°©È¦´äŒ}—x·Îq˜ap—fx¢Xy¥}¥Æ‚™º[‚¨e‰©‚‹®}q’cg‹`r™Rg†Pb†FYrS•`‹´by G_zRkŽUaSj…Qw•bx£Vo¨cw¦ht¦}•Ìir‘ZfJbSt‰NmŠZ~¡f…™NhƒSa^m”€¥ºg|’UjYy–JfŠOo™^‚®[~²dq›\g‰Ob€HY„LbŽ__ŒTe\lXl’e‰±s‰®cw‘[v—Xl–`s”_j’Zp”Pp“\pq‡œd‰›GZƒWtœ_oŽVb|Ma~L`xUcƒr|¦v³džHeySvxM{~I\ˆggl^leDwmDŠxC€…MNˆqPn\HfJ@d?O\5\a4u_Gp…]`ˆlƒxUƒžQz³i[—{gl^^|HK{JGbJD^.Kd<[i8fh6vK^”Y`uoYqMclIZ€@\rWPrAFl>PZ.V^%mn4z:_May_io9‰…Go—]\†loZ‚{EŽžTl—_o{TpŽJr~K{r?‹ŠIÿ—aÿ†Xÿm,ÿmÿ€*ÿ’XÿzX¸P3|}E‚N–FpšnuqWZ€MDnWXaAhn4‚}<}ex¨og™iˆ‰^|ŽEuœLd—VS|awrZt€3y‰M[žWNv_ggBgM]“_“zb¯wh»¢]‰j~9f¦_’}?ž§F”¶¸…©·~‹Å€Š¯s³Q›´o»™f³¡T›Åƒ}Õ‘€®„ŒœbX“œ`†˜Z‘£J¦Žl‘³_­£gÔÙk†çuV—NŒi6·¢H«ç™ŠÏ¢ YwŸE—}D»»^£å zŇ‘ŒPñ¬C¶ü¸Ä’xÕsoœO€~Gq„|™’>~—bŒ|Xs¬Xy¦…’W‰“oy§a˜b‰ªvL‘nic5—ƒ3‡EXl{r=cœP——}±^Ç“€rÉcWj7†lšÇc‹Fs|Kf“A‹¤VL¨Òm‰Ãm‚f£¼|j•‰šœm˜«r¾Õ~§ëi´¹A•Ýu¥b‹iƒ•Z€“nyfx‚€¿ _¬ë€»Ås¾Ó¡¼Ï›š¼_t›[lvVެ[§T¤8rƒ2¥›“ÃèѬçlнI¬_›Åy¤º]x©h´wg|E¾kñÕl¢«k†[j„9{˜O‘«Xg¥Gh‚=wœM_ŠKg…En„I…O¬¹q¢àY€»;{”:‚•Rx‘5‘±[l©Uk‹Sc:\{?wBs™I‰¦d˜Ëkq‡avˆEš¶`¦ÒkеRv¥JhxQs“`hEd‚X[wCOm5Wr?žem§;Py9`zOp_o‡RŠ f™¤v‡¬mž¡_¡¶_™[„™]… d²ÊªÍòºšÈ[–T^ƒ;v}f¢q‚¤C‰˜s›ªl¬o–©YŒQ™˜f ³i‚¦RtQÃÝzÑæÃÛŸÐÿrЏ`ˆ¯Sj•]kKZv=žTz\‚¡c…”f°ˆ¯Îqš´vž‰n”b~w›Ð^ Ätª×йЫבÎð›çÿŽ¡Ã‘œ¸·–}¬gu£B WpŸAu®4d‘7p‹@o”\f‚eyžˆ‚ |l†VXyV r—µb¾ãkd–JU€MbŽh‚t›·t{¥]c„`u”c{§hs™OX}LY~Lm~DYvYVl[V{LLkC[zEV{DZ{Od~]mŠe{’\ Ra‰k™·oiƒL]~CY}Id‰Kh‡]~ wŒ­[}˜MpŽRj]t}Mo†R”¬e‹ªVœl›Ä½ßr}ªc{›Sx‘_yœ]v©k™Âkƒ¥OZzASwCZ…h…©t‚ŽX^ƒPh“Uw§pµ´Tv”\}‘Xo~Xo…eavŽFY~Qw™b{•UmƒJgyI_tDVvb|¢q€®q†«RwwJdyPelMohJewMloEgyEhvEljMIiZJdUL]28f4COi«gŽh¸¢f¡Ê‰zÎcfšx©€¶¿‹g¦e‰@|]•©™¸fuªŒtRMsJzb:^‚F‚†E|›ZÅ‹T‡µaf¦[]€Qtt9„›=˜š_}d¥‡HnMwm7^b+„W#¨¶^§ÏZw‘f\‚ae€4bQ«f“Å‚¿[’¹qa¨ŒƒzNsÃKiŒaz’FŸªI¹ªl®¦eÞÐ_Ïô‹§¿§¿q²ÐzÊ›Œ£W¹«Y‰·ƒ‚¸o ©d¤¼™€Èq„ŒDqtMuˆHžy¢©È«u»Ø™ÿð¼Öÿ²·ÿ˜“¿op…p€]ÃÈU›ºŠÜ¿SÖÿÊÅò…ÒœBšû¯>q–_]?€c?b¦L[~=asBg•EqmCj¼2MLJªTˆ}Y\Ã6šx)–šF™ŠB‘¸?™ @³¥xÒÛ¥Ìÿ½ÃÖ»Ù·lÍþ‹pÉ„a]¹¨…ý…l¥Z¬¶^‹¡‚¿æqs‘{™WÕ°‚ö¡¿ÆQ‘ç‹q¢Pzƒm®œiª»WÁälˆÀgv’B£¥C²ãY½†KuV†`'†Õk`£M]:G]/?\.>R:=J.WK(Kj2PhJldM‚n=j—[^‘wcuWowH‹ƒT}¦`r¬uidY„]UgLPbCTZ8Wa5gi7p;o†P^“VRvPKa=Og,gd+\w.dnH~~@f˜Gd†WWmCT^<^k3ol0Y5j}Mx}@h–dwP§}P–ºOœ´ÿ¹qÿ›cÿe&ÿlÿ|(ÿžPÿ„nÿYH¤=#xx-z{L}“ncœ“D‡¬_j¨gz“js’[bgWmUvmC¥?œËow’dv†LsEo•P’ŒRƒ¢T“¥eŒ®bušyP•\woPÄ’4xâjW¢w\sd||Ly¨Va¢^uŠ\M“QqvT{ŒWe©^_€Kc†MœŒK‚¿G§q‰¯d}¯t{—o‚˜{—‘[°¿cˆé°‘¯¥^‘ºyŸ©qœ¿n‘œªˆÊÇzªÒgÊÌruÈvc‘Rp‡F˜‡`Ь•w¬h›M„Oo‡_J~C[b3^f8ÍpP£Ö˜œ]˜­b«¡E Ox~P†…a‡“R©‹V}…Jo_ng#}Ž:—–bqQª‰G©c‚‹O …QºÊLh­‘¢xkŽ„m|i²bog]——XŸ¹¨¦˜¿þ䀿ÿ¼ ÷YØÛny¼wer_[„E¶˜0sÃb‹yjF{wJ'r”6Zb-‹‚=“µKˆ®QUqcÁq6‘žf’F‰–’—µ¡®Ê®¯¾}Å̰Õÿ¥‘Ë_·¥\€Ð~… Mƒ¿|²¨7…¿‹`’O`†-¨¹,}Ø ’†˜zϱ›NpÄiyqX™°¢z ­y~yž[ T«°†ªÅΗ˜H´¯Q˜Î€[u__fTw}<ˆŽT†šbµ¤g˜Ôª‚‚”@q[GnxB•`D§”Z¬¡v¦ß‹„¬ov•C„£ax\w•Sm‰Jk‡r„L]mWŽ’k†Ã~ZV9aw:o]Hf0_jLm‘JšMo‰Q€ÀTr™Or‘_ƒ¡H|Mxƒ@xŽEi‚Ix™O}‘Zµd–”dÁV\ŒAW~VgFc~b{”Pl‚[y›uvœjuŠEks<`d2NoBaƒcrŽA\|Vsšiž²YrRz”`Šmš±z‰©Ws•SwSlše|¨y‹´p…–sƒ¢žÈ¥¤¼_r‘az–Yt”]thw•cdŒXpf ^h”Zm\q’KfKnˆWtŽu•¢iw‡_wšTo“Mf…^l’Xy˜Kl‹GoŒYw”b…¦r–´`ƒRm”g‡°j†¤dp”SzHu\€”fx•]m‚`[{aJpLDeI7TG=M>GK,:Z)=J1;U2MQ1[U*Dq4HVEKV5dP*^pt›}¶Åz³¹:×ê„~Æe€€K€uGŽN€B”®ˆ¯¾|“Àh–šj—¹V‰†L~‡fuuRÅzf‚¢rwƒ;‡oR³ Xœ£X°¡V—Ë“²u¦¼W®ÿWg}Gw™p’{fƒ…NÑÿhšÈ”мQ°k­Å`§ÁLp¾Oj7i†?~–JyVh–BmvFœ²²u‡Zw…uz†PŸ´W—Ñ_–C ŸC—JŠ™Uk…8fŽY]q'£Tn“<ŽP‡’ZÊð}„ϣʟn‰NºÎ¦âÖmzhmœ]“¥Q‹ÉS™m†µt}“Yw‘[«d‘Âup˜g\tLYt5cwS‚ˆH´Õ=sºlYpBhŒ>[w8lyYW„8\‚?Tv8m}L^~Qp}qmQ‘ cjTv•U}ŸIz­El†L„¦Y{ŽV°\“¬g}ªma}D]{@Xv2r}Bw›DгW«Án…¤L…ŒF—¬‰–¦s|¨Xg’OŽšdšµn„¤j~¨Oi›i®~o˜hšXl—P·Æ†ª×f€™g…œ}©ªwšs‡¡ox™W€•Xu˜^›«V}§W—^[{NQq@WuFmKMr6;W2AX;i}Lg‡Q[†v‡§{UxMi}iƒŸpbSSu;s•h–Á‘…Žnœi¤y¨Æ’Ñý˜Îé«ýÿ¦»ÿkr“}¾Ý¦°Ý•f‹cr…h‰®h˜¼X‘Àz¿õ¶Í˜Ìñv‡¸xz¯]k›Fm˜>\ŠETwAiˆpŒ·sƒ°ƒ}¥|‚hv }§Æ‰¡·`s˜sŒ§_Q€8RxHjXapKVfCZjCNf:H[S{Vh|Dk†Q\‚OcŠIq–RvAqƒLk‡[hŒLm…RŒ_jŠUiˆIk…W‡ gy“bw›[s•Yv˜Qq’Y¹nŽ­dv“\|™q¬Œ‘¶^ c£Tj“^u™er—Xq˜Yx—Yt©l³Zi‰QmO`…DaƒGdy\m‡Zj‰Uq’i•¬`‰—Zjf|”[z‰N\u[fˆ[gƒrxžo} g{•fy¡hw“V€“Ey˜L‰Ž^|žhZ™qreghqOQzRY`J@_;?P=KK.A[*BZ:>R/:T*=J'/F-<96OA)aPng.`|FUrK]^>Yf5SlAscNg|APpMMbA]\6gj;lr9u€Gk}SS†fLjWU]BW\7Ts:Zn9GZ4FR5ƒT.n‹- qM†¬FZ¥pcU{zHx’Ed™_^ƒRUyHRZ4qd*Zv9‡ylÿhFÿt8ÿf!ÿqÿƒ+ÿNÿˆhÿmJÿY0ÿQ)›H5ŽœBœ^’ŒPzœk´QŠÏom¤®‡ztoVq‰RJˆSioX¿{OÉãu“ò p©‚„‹c‘—O·œ]ˆf”bFf?]L/Æy5h÷r‘…¤“EŽÈN–·kÑ|cŽZ`ƒEWˆP[rEpvAtŽ?—=‚·csŸVH“dea8b’>D‹AFi$Gd,GaNie$i;g}Fy‚?{—V„–eq®tk•Ij€Eo’Qe‹S“’IŒ³pŠ¿Z{½^l²Rr|]|J™ªN¨®_†‘Qs~Le@°ˆPÆœc‡µ£ŠPŽ j‹«l´}a‰c‘m`¦x@¡¥L¹œ_¾Ùsƒè†‘YX•S‰vN¤©dcÃ|€}K™¯k»°lÒÙ`ÂÝ•´†¢·z­œ–å `“¶wÑ•€­¼‚©“c°b™ªpªÒRs¸iwP­‡^œ½uˆ¤d’“IŒµcz®fVm¨dŸ‰=c}U|pBRd„h–t4t´A·†0\´{Vo3jg0j–+zU𬙂°¢³{{u¨zH~FAllW)ĉ@Ïb…¦E{¯duˆ2–i¨–W»ÍŽÈüzˆÔpµºU·Ù‡Åៗôž¹ÑcºÓ›Æù¸½«¿Ôƒ¾Ìƒ°ó¥†¦ZÁ±uÝÿ¼Ÿôˆ®²”¹ÓxtÁ ]Žbir:®–>¶é¥¢ÌM˜­`áw›Æ–~‹‚ÝÒ€«á¨}¼š¸½N–핎[‰Ær8˜ßMàÍdÙúžÜÿz£ÿ}­mºÌ•’»K›»TÑËsÒÿv—Îq•²w­›l³Á‘¾¦KÆÑcº™Y‰”H‡vIÖwQf‚s{zHÆ„J¢Çnê|—釘¡N’Ä^\…CdoVr{]a™BgLÎrjŠZ¤¥]„Äql’=o`f—KˆMk”W¬›hã_g‘O€‰Fn=oˆ;}¢R”¯iq s†—yªqš§b½\sSn—CyŒ5t¤Jf•1Jk*vvAc†+uBy¥”Qi5}’8£Q©­‡a¨7\z*eŠ:¬­zt©\ƒ“OŒÈbGVFdgGs€¹qQ8Od+Zn/}”LŽ¡J|¡fo…L’²KWz:^u9oNh€EfN{œJuT\3an?w—Kj„O~ŒWw¥Uq‰Su²M_8›±jv”H|žPr™[| Z„¬if’v¢hvPm˜Y‘®”¶aŸœ¤€±c¥°_œµZ¯Ún{ŸV³`g•KpšOa…\ˆ’o’¯[Lm-Wr7?m&J`.bŠH_x1Zs-Iu*Us:Z‰7Ie:f„U6Q3k{Tr–f‚’gŠ©Z½j…¯\‹®Uƒ¨Z§Îdm˜h·Î˜¼“ÚöÝÿÿ¯Ýÿœ¸áz™Liœ@~œf¹ßt‚¾x±Ý®Ãç‡x £Ë“¡¾©ÎvŸÁpµˆž¾im–X¨kpŸVyžTmœFf–Yˆ®ršÅtž»b{œj|¨_‡¡Si‰DPl@az8Tf6\nG|—Ba~=UiGrƒNw‘[‰›b”±¡Âp VVxGj†P`‡U|‰`oˆNf„MbDd†\p—cqUlŒ[p”[mQpŽ`r•e€¡hަo¯iŠªzœÈvžÃgj”Rf^t—jz™_r’akŽc‚±o„¨XgXu—WqœSvžHZ€JZQhƒMg…b~¢gŒ¯Yy]jŠYcBSzHb’Ynšby–m|›_b€Tf‹\s–YmˆOj}Ny}`]‘]I„ja]_`g8LuIf]OFf;BXFMU;CZ-F[BPX31a83I))=#;1]=pb%Y‡6aqRnnKmEmyBWzSg[Ilp:g~VXxT]^9zo9qCn–hdiYvXQoS[c=Oi3?lEGYEHM1LU3[^.ch$blPinDh’_‡‚Wˆ O{£XwžkušfW‰RPp?Zj+\f.‹g?ÿm6ÿq3ÿcÿhÿz'ÿ›Sÿ‹nÿiJÿK+ÿ>%«M(‰—U•j®Yz˜l’ySs²h\‘—™fOš¹Q}³d€‘hh•Z¾rP¸Âh–è¹u´˜’gްY§µu‰Æ‡s¬iGŒfyW3»-•ノ¸‰m¶x©[þÁfÏÿ·Çÿ˜ŸØwc«db‚G…4ˆ¢G‰®lžªm~¬YQ‘jvxGq˜Da¬OT‡H‹y-€©C†§>Y®K]pLvz2­¦T“ÂTÁ®P°äukÐytˆbŒ˜Hy²a~¡{†œU‰mv¥eo[v–6¦Ei¡T‘~`õEçÓž¸râ{iˆÔœpragQugLˆA¬ƒR¦ƒL¤O™ŒCuwažŒI¢¾rr̈iŽOsŒA“ŸGwšjg‰aŸ–O¸š‚´rˆ¢Wn‘edmT—8¬xt‚©w¹†a‘ªde•YskBÍvSƒÉ~x}oyŒC|vS š\–Ä‹k¥x™‚n“¡j_ˆA„|J™ŠKhwTm…>~–FB|Nll>p]d›=nd…ujy¥‹éÏqwѺ̛Uéü¤Ãÿµ³É¦Âݵ¬ä‰Øú¢ƒê­x{@rÁPkDt„S” ¥£«±“ȰòÒ˜ÄüŒ¡ŒLàœžÆ¨w¥BÆ–`®]༃¶Ä\»ƒxÐí‘Æ¬~Á¨ˆ}§ky‚L‚“cz‡T“šU^©@vrL•¦n}•H’†Vs…^yƒe^y4€9…“R…¤c„>Ž¥T`x=ª®kx™€hŽJb}4zN„ydŽL ‹Ujfs›MÈ£¶ŸÒf¨Ä|­ãbŒ¹gnYÂöLz¹A‹˜NƒŸOz¬<‹€Yš´™›µs“¤rwªS_‘8l„\j‘GW‚S>BJ&TI'yZ!†‡9cŸXYxdahEb€Bn{Pa~OcjPomGq‡YlŠ^vtS|‰Rm^i‡y`xglxUm…QtƒJN…M?nO>\BFO-KQ/e`1[i+hi7mf9„‡9‹£N–]|¬hƒšmŠœcm¨gZ\Lx@ZW5¼o/ÿ4ÿn.ÿa#ÿpÿ|(ÿŸSÿ…jÿaEÿD"íN$k*€ˆNƒU—¡]±rŽ”c`žOsj^°E{Ès–ˆo”o\|k‡hOw“Fp¡…p”eŒƒW|®o”¦sj¯||‰cfbˆ„OšµO|¼yk£lsƒh‡ƒHÕ¥MçØ©Àÿ»{ôÁv¤o~˜]ƒŸ?“£XŒ¿rp¥f…–h‡’I¦[k¶fyšU“ ]y©[›™_íÌV‹ÿmª{ª7‹Év¸µgÑÓy¨÷·”ÏŸˆÇ€§Xƒ®€ºx­§U¦Áum¨yp [oˆ:aQ|Œkq—l—¡L ­|©œ·blÀ~z{~Z|Cvr<“ˆOÿ‡FèÇ}{´Šl|PMr5RV?n[Aizi}tC Zf¥F|~KžDv¨mw“W}˜X~§Y`‹T†Œ+u LzXa„G•Yl|^„a6†‰?Ù kÄÏr¢”g‡Ÿa¤Œ^¤°ƒ¦Î±¦¹“¬ S‹¶VœK®šHµÀk€Î›~MUqO\tGl…LVo6_v%qa)¼›C…¨†zˆVvŠSœŠB‡È½Š}D®¹X±À\Úpb¢;šlT†Às¶R{·{¦‹Vÿù­èÿãâÿê‡Ù§‹©Y¨¥~¬ñ¸›ÐáÑyžôÁ¹¾mPA°i/¹ñŠ¡¿r¿¾€Äà[öÿ¬ ó½‰šctˆY‚”S~mz°E€|S¯³Y–â]¤×W}“F‡®=l…Wl0mž9~?Îì…sª…°ŒbèáÀ°ÿÓµ¨™À놧Չ€Ê_b‹Ry0£¬q¹Õg{×Tu}5±ÔY•ÔuÀÎŽË©­‡{ÖÁ|ΕfÿÅ{Ìÿ³ØÏiŸÿêQnQ‚l2À—‚±¡qÌ­nº­q®¡ÑǾŸV¬·Vš8‡>{H‡ƒa˜D¡ƒS|€CwŠJy†\”‹[s¡u…—Mg‘Tcv8o€Ev‰Ds‰Lb{/w€2~¦=q‰G°—Q“¿l• mv¯\Á¹Ä·Û˜ÒÔ”Übœ¦h¥á‡»y‚¢W´ `Åþ® °]«Ô~„t’¤ck Ky™[by1oš@g*cs>”†]•Ìg¥³“„«aVy8]p@`kB€‡X–¿e‡¬Wo‘Bb†JW_6{J…‹@¡”Mm‚F`nPqlJn™UUx;w‡qŽ¥eu¥Ju”NRq;Zp=YxEkzStŸGl‘Md~Ea‹Ocw?r“kn‚J”½i¡Åt„¤S Dq–F‹•]kŒ=w…I`tHXjFWpPNk5`wV‚–O°V‘º}’Àoq‘ROk)`};¦Ù_€·SyUq—w™¹m{œ_u f¤Yp‘OnŽYr’_mŠekfq“ep”hos­cv™js˜\u–Vt–cŠŸv–·a‹ Z‚ Ru—u“¿}‘¸r£_~‘Mkz?f}>^wI`zX09Q8CN1DR%ZT4h\2Ym@MiGW`#‡Nc{9j|Bh~@‡xOƒ†V’ai–Z{eX‚@r‘gŠ}nŽ”W‹šd¯P—±^›¸wŒ¼aˆ¬Zj±p†œo†±lˆ·mm½m†‹a˜ÅNlÅzZ“w“yIw»DVo€hY™’u}­…j‘m…>p›B„W„Ÿ€ššOv·poP‰†I„žg•KjŸiN|PPdF£s/™Î|Ñ›m©TiŒRu”:…lŸ°•¡ÈŠ‚Ý—y~xžXŽ‚«Â[›ºrÀÑbˆÙ‡i–ZyŠJ…©Yª¶bƒË†¢V®­O‘¾¤~¥p{…¤ŸI•Ógv°m–NÈ^ƒœ†zoiuqUCV0TH`h#Qf3_jMp|Qiq2‡ˆ.Q±tcvAuŒ&U`bnGg~:}‹I 9fˆjx}RutKwJfƒAz^7b}3|hXˆ‚Z_l^\P§»I‚Ã…„’z‹¨vr|ZŠ{Yw¸^uZu†Z¦Ž;œžiaˆWi}/qo8kª@Šs-™½R†Çri‹?ˆz@^”lkHžž?‡£[ª¦lÏs~´i{©JL‡lbn]qtIœU¦Ã€öÿŠ|ÿ¬cjvw…R y@¾«Í•]Ñô™ˆÚ ~i¡±S»‚=‘Žz«žE¦åm¾³oÂÁ€¢øˆ‹°\aœ‚yE„}Wb‰[‘wƒl«3Zt3Yu({Rm{Kk‹Ex[˜VŠ bu¢Jh–AW~7q‚L~£Xf‰KZt’`hKc“;],Xr?X|?XlJUtHOf3F\8j€Mtš?k„HMl2b{…Œw¸PuœZz¦ox¤}nŽOp™c|•v˜²ny£]°‹”ÉzaWsˆV}˜iy›Y¯]†³Yoši¢mv‘ez¡UcˆWtŽMw{Nx]¸À}•ºNqŠFk‰Kiax¤q“ÇlqžN k{¢^c„@lŠM‡§P…ž`r•eœSeM]„Kc‚\‚˜z¨Äu•­h“¬TxMv’k˜±}‚šp„¯upšio‰mhˆWc‰P`}<[Af‹E`x=ZpFb|He…Ef~=UnEYtA\wLg‘Vj‹O_}OlŒWoKdƒCUu:Kf=UtBX{L[‚dadv“Wl”m­[nŽOlQ]HVuL^P]‚]fŽf{£u‘ªo€žknpƒžap•kp˜{žp}¡ftšiƒ«‚Á‹ Áu‹–YvNhxRuŒNt‰K_xNmzJTd1P_1Nf3@i;:V=?V2HQ3>]6?S/IP/MN.K['Jd6X`9ZoBbcLxgEcq=_sJlrIiy[fxTs}H~{Do‰Nq{NVqPgRIZff`Ez6s–XxŠ[„šhSmnu`vy<•ƒU£Usªw‡`ÿyHÿˆCÿe2ÿg!ÿk"ÿ~*ÿšOÿ{qÿM9ÿ9e4_c.yl;f >iyOoj:zzDh’SWtLpx\š^R„e(uBo?"g9M…]‰{@s­Ci›^z€Ml•Se—xdPg€Bc{Ir|1I}H;k4Ia!bogˆS©¤UwÑr„¥g]ªGr‘O„Œa¯¬cyÍ‹Zlj€Sˆ=‹½a”¶}—®^[´}uAŽžVv¯{MŽgsbNsxG¡ž[n§kzGƒ}jš¥\Œ¢†­´… Ñ]ÿxyçš‘|YvƒVZ|]oj9rt2`‰9qo(™‡6Ÿ¨RÖ¾Q‘Ö‚‡“m_›XhMŠC®¤Bu«b±’[z’S™‚:œšX†¡h«ÄU‹žrkhNsXÝÅFh¾}W^:^GG—z|Q®g€a5›ŠK}ŸOu›ZˆV¦‰g™Ñb¥«ir§i ŒBv«V§ŽK’·Yy™i”§usŸraƒA®”C«ÒTŒ¶†Z„D[VJ¡¤F“¯v¾szBY‹C|j+«ÇKŠÒ‚´¦›¿ø»¼Ô‹Á¶P—ˆPÙŸ|½ÒeÃÄÊÿ’¨˜g´¶ŒÀÐkŽÎcÊ‹S–¤n§Ág«¡[{YI“Mxu;œAT BŠe6ͯª™ûÌvžf•‰]cYn‡Hœ”<|¾X€“U²§wŠÎ|«zÛ¹‚ÇÙ°½ÿâ¬Ê†¦À°¡Ÿyÿð›ÿó ¾ÿŽ´ß›{¤oh‡K†K‘¹’€›{k‰fz:gP† {¯Us–6{žBq|L¦h‘¯Ž‹Àz¶~†²xp‘x™afƒZ‹©jmž?Zs;m‡Dp‡LkQj„G^€T\wEnƒO²n“Ë‹§Ú²³ÇwЬOw™T‚ªg›Á~™Ä|v©Vw¡Ol©Hs¦Ux­=e‰ROxAV}R{©fŒ¿eiŽPwGl’Vu’[­×t¤Õ‚´Øv…¡Q¢³g¡ºb›½|Ê눱Øo~¶m–²i„ \Y®À[˜®T›¥NuƒN~Šf‹¡drœV|œX}¥l{®j}©qˆ·l}°gt¤k—¾X€«V’_ˆ ^†²kœ´du—Oa7V|@]v]’œh}œV|•^‰Ÿdp–[l›QZyTz™`n‹PhNl‘Xˆ¯cŽ£Ga~IjR‡ƒ¥±dƒšžŠK…fnvJ‚’8‰˜K‹µB~Ÿp¨xLuO\W:Os:bg+~…Uƒ‰MŒª]Œ†QÿªYT¿ƒ4>;S1$el*y{Gƒ±?g¬Jk=€–N½­<‹ÍiÛµy±Ûª|¬Z™…eÅè`rÊtbp“IfeOYŒ~_n<`zQpWSºšKöYm¶[¡‰t’Ì^t¨bƒN¦ÝYg³tomYm‰f·“~²Î{ˆ¾kFu;m[$š¯kŠ®t·q¬Ï]³ð‰~ɤ¨ŽdÄ©“™Ðz†m£¯i›ž`K‘X|m%{ž^w²^‡;¸ÆQŽÁ“~¥k¢Z©§rÐÌhÀÜik¸‰:l,ÎaAáÏr„¥U°Þqˆ£‹vNkNwo?·‰wÿ§h×ÿÿˆ¡Zˆ³h¥¿Œ¬[¨·Re£Mdj/^—w[X)€©(h¦?À¹bÈØ…¾Þo¸ÿzu¥˜”‰“µÇ§žÏ·uœo°—j²ìv¨˜‡À•oÂÜ‚¨VõŒr«Åœµ¼lÈÏ›¦·w¡¬g¿ºz“¤kìË”…ªl—«{ŽaŠÄ€t’^f…Cz‚GãÞ™ˆßo}|PVsHjvD†‰C«p„«„‰“k‹Ÿxn;tyTÄÇNƒÃUœ¤r‡¹€]|:h“[L[-Ç¡g’ê€T\dX_I\yB\c7ƒg=‘ƒTVxƒU–w«Èž¡³b«Ço¦ÝnÀþjÓUk˜1]|1vyC™£Mzœi­q¡Ã}µØ€’ɤɃžÎp‡ÐCm¢Nz¡D†ÁNo£6_ˆ8¤[Üÿt~®?vœ?rª=iŠ>}¦Sl”@\}7q‡:|®C³Ï€Àfj‚C[Zl~\u†Kp>l‡JEf‚C–ºw‘ÃpÈvjš\€ž]çö˜Žº|Ž’•œÂiwžI“žqŒ¶h“»vŽÃv‡·UŸ²d˜­`r„z‡wÀv†¸i »j…±ot“¥¾‡¤ºŽ—³cq–ivŽw”¹~ƒ°hrœMOg8uš\Нe¢Ã„‡§Q²jƒœaj†\{¥½fk‹@xŒb•™uÁº‚ÈÙ«»Û’£Ä„¡¿z„ªrƒ¤a–¢tœÀyš«sÊÌ‚‹£Lq†>|˜gŽÀVYKX€Xu•e€ x‰«np•^e’Yl†cª¥bsˆQ]~v€ ¤ÙÖ ÀdpŒDl‰Lm‰GbŒ_v§anžQp¡`‡»tªÆ`uEhƒJqV›ªfŽªfxŸySn—Yyd€JWp;h‰W|—dš¡oŸ`y‹zƒ™nnŠY`~AeyJs‹L{–b­\{›QhˆNoŒYm’O`ˆO]yBYuQ{š`v”Sg‚Lbv9KlGb}MczOa|IVzNY€SZ‡W_‚Wi‹Xc„Sj†Vi‹d«rŠ¥b…‘^u“Vj†Yu–Uo“Jr“Y|˜`~Lk‰IlŒVuŽLQe=`\5Sn1LkLIXEGS9PN5UQ0\P+K[9UT1QP,OY3PX?l`=fi=mjJ{lAi~Ybmh^]OWcCQdE[]9Pc5B_?DR4QR(\a*kn;oƒ6hMa„ad}VY~JqnGexH^vR]ƒKbzLV„Bbu>cv=b|‡G}“YˆV£˜zˆÁ”rœ‹PŒeAoPCTJuW5…~<Š£f…_‚¥ur¤{M“†_c}b…S|…P…—K” _f½cl…lg|LyDu­os“V…rQtWM{=cb§o1€³Nk±‰g”t{Ll“S`Š_n|@`z>RuCWr4…r5{ªW‰“nb›o†{|‡at®[]¤Cm€Bˆ“N€¤Lu¢Tl’bT‡OEe0\N.Mq>Ri8Qf2bd/_h~ARxCj_;„s9e{>v`F”„Q©²V« M€‰W–œ@Á¡lÿ¡f›í}»žž˜^ÿ‘GâÔeËË•Œ£¶–w[´²”ÞÖ‚œó»´•ƒ~”¦‘MµÊt¤Ôƒ™½d“vžƒO™´mupdYrCrm2€q>S‹ar_BvœS‘‰S¨€XŒ¬W©Ÿ=öe³PxÜ»ošbpˆU–‡D´Ç;k«˜{ƒIrSvrZ†›Qžƒ@¡±ž¸k¶lZ€Bƒn,Õ:T§DZZ0yk>‰§?k‘i —yåg~•l^‡a¨”3£¿~¬Üâæ˜Âø”¼ßxpÏd‡xJÓ»PÕ÷n‰Þk¯]Y—pXo*k_;‰mI^oW˜l?{É“Œ@ÄÍq½æ¡šôrŽØM_„S}†HâðX”ñÑ¥_˜œyj´x~€Ožªz‡‡hq;Rs2‡‹ Ã^`½={À¦›ÞÇ­ã¥d‘<ŽŒK™‘zÁœQÍËõijÝíyðû´™ÿ°\ŠwVkHUXP®{Pûÿ®¦Û©†»h…‘E›¯L•¾v{£†E{;>>#dj‡z:ÄÞ”äÙ…Ý™–…d—iïÄ™¥Å^´‘m‹¢ƒ’šv®Àf¯ÓVØÃkËוǵiÿûÀ€¬j– ce‹TcSh1EbC]zGTkGXsRmˆSm‰N[{DZzVn…XsŒ\~•UeŠi€žzˆ›lw‡fz’^r‘QjRrŽZv˜aq–bi•BRp=KnP`‡TUsE[e7]h;_qBfaCLaAfQ:j[3o[5bf6_jDcZ9N_9IQ7gW4mw0U„NZdN8_KODNPF:XJ0MW2RW4Wh3Os:Z_:ir.e€5czFVuCUpN\iNMqFDeDRZ:V`7^kF`wKjsNgBoƒU{Gl”Ir„SpEmˆUttQuŽ[|’[y‡Xv—Pq‰W‹UŠ¡L{eÑ‚bÿÍ\ÿ§…ÿa3ÿd"ÿk!ÿ}'ÿœUÿhbÒ;0‚VZs1PX#fb‘Ež_dÐdswWi:>…PKK2[i5‚v2‹«r…§v’¦`ˆ·yušRg‰UZw[FrJPF4Ym+[v=FsB@S3VZ/€/‡ŽY^ kkyWsk4Š}5¦~:‡ŠGž|O‰T|VäŒU™ÿp„’vüƒN¿ÃŠ‹›s‹ŒkÄŽ]˜¬nÏcÜ™ìæ{ªô©š¡šÈµµïÁ‚²‚±ŸOš×“¤Æyp§ŠkWª‡GU´€gk,oz6wˆD¡ŠMz”x{ˆf»‰Tg¸„Èo;É’nÈ¿S؃•H{Ãm˜Tl“Fso8…™Xª]…šcòn]³ojt4‚‘@U›YyWS¢_Á¦Tà·xvÔ°`qs€4z”5|‡c¬YtÄ\„ˆ]ˆœbŽVªäpªÛ£¡w˜Ç’L˜{m^Xx°]œ™\‚­kÀ¦sb¯¸ƒJÙâ~éÔy×ÿµ¦·›«‚£Ÿ\™ºs¸¹|Æ—™’vÔò„¥ùt°d¨½Vx«šm~}Ä¢M§ÿ·c³ÅN×Ì¢Þf¡–TÄÿQ¨½:“º‚ƒÃrl’{‚eGŽ‚U¡àŸ€ dŸ­Pz†Cç³g®}ž°t–š€ÿõ²ÿÿÿýÿïŽÚ‚r\¢µ@ŠªUd€`nT|¦dQr@^^/‘‘f‘´xŽ£RÑÉ|ÿõÊÎÿÒÞħ|Æ‚€n<™€V­q§—½¶x ˜pª¢l†•[¬›Z–v€}Hü«\ÍÿöŒ…3`¬qOc+@mON'|™E–©D Á˜‰ª\¯ÌinÁC«¬cËÿô°ËŽž«‚‰ÄkwˆG…‘KŸ LŸ\YBc~Ld>pŠN”¬^|›GZ€>…šVšq„£LƒGŽ€;š„jè‡Ã´°ØÿÅe®Pb„=krQ`€;£”‡óÿ¬ôÿŲژ»íœÁئŒ¯Ž{‹hq„biš]“jz„an•icyYd˜[h€4`z8pPeNT‚Hf@Kp@oEd—R‰§gyŸ`b’6PkMyŸO†·^y®b‰±Sr•Vq”Me‹^i“[k›Lp¦V…²\N}>^‰Pnšin‰j} g›¸[¡¸b ³szœp™¼}°Ù‰°Öfj‡J‘šm§tz—pp‘Rw™GtžU}”l™·w¦Åm’¹} Êt“·Wƒ—fy–T¥À––¿U]|AUHl˜\´Öj³èVy¨Nt–\Äs·×|Åì¨ÐÿŸÆë›©Ñe°UŽŽdœ­i‘Çi“¿qĨ¿ížÏý’‡§j{ª¨É_žQl‘EL{LjNc‡FjGW‰KbŒ\{–d‰©‡¸Üs†–ItƒP—Fp’S{œj¥ÉÁã…¦Ä]{•X}•Ti‚Nm–`~£V¡cp–VeŠau˜Rf†@_sQ^vLQi7Ki2Eh@_zFZuAUrQhxVdyHcx=SoPaˆet¤p‡¬i…©t f{™YhŠT_Xl[dYaˆ\t–WrYtF`z9SwL]ƒTTiSTa]X2Yd6d[Boe:zrEayFaeIa];cn;juIxtGh‡@VŽQYjUHU2gC:eN'iN7]P1f]@bo9TxAt^B…ˆ:fœML†VIYCP[:HV:Ia9PZ8\W0Yg.MhDZc?hh@a|>fwOxrG_ŒOgU`yJepBevExqKpW›z^—W™“o€š`WŸpNulÀ[Bÿ¯Pÿš—ÿd5ÿb!ÿf#ÿy%ÿ™Qÿ^bqA+cn'JwJU]0sb E<<\KaX({…?{ŽEB”]:YI8L9`@.5c/BM8mW"OŠDJmJYj5X|?[v8Q‡?pu1r–DqŒ>d‹cz’L8JnNG™8xµj‰œd‹«W~”\S—Y`o?^L†|JŒž[NˆMbW}s.› G¢®`ªÉqrБt–{i™S\ŽSk€6w“9lŸUn‡R]Ž^hvT†Shª]]€X_z8cxEcƒ:X‚H`zS}ƒ>‹—Hf¬]l‚Hš~E›ËdxÃr~O»¼N©¨\”§\®¼w§ÆV±ŠR¦¡]§•w£§ƒ†U}–ud‚P eS¯”H†•^‚‹I®o_¯Š‡y«Æb{`KvGkK:ŠŠT€™Kv™bŒ¢bsh‚„IqR`T‚]thBG{?D_K‰V#” ^t¶MryW¼k’–h‰qO¯TŸ¸uh£Hk–[t”H|6“œIgªLn†:§Om¥ylmih~=eŽNd7MV+rƒFl‰Lw¬eŽŽf­Ö¡{¾ŸbŽ\nw\{zXd•\ŽšD¾Ãny¯tž®uÁ˜¦ªNf¦b{<„‡-¯ÑG·Ð¢ÑÅůOŹhÿÿ­üÿÇÿÿË©ÿ¨vÂ\}@x•B•¨x“J£Ê—y¢SkˆC«‹LüÏxÁ¥Xg3Sm(©ve~ºŽ¶œ“†¼q‡;_šL6B*xv$h—>fr5’´]ƒ†?ÙÈBÇЈ™¼jb’[zwx™gcÁ²h¸´iÿ­tŨqº}f£ÂXøvÿÁ{üøeã÷•ÜÿWŠÓOª»}°g—Õ°Œ­Rž·@PŽ1ihšŽ:ÔºhÒ©v†j§§f–Ägu“T¬ÇnЬލ§l•¬P¶ãm¢¶sªÄc“ÀUv°E™£^”Ùjƒ­@n†]yLŒ‘XWyD]tAMw5TpJk‰UgˆQp’`šf\‚>Rr=iŠQ{’VtŒf¢³j£Æ\´ï}¦Üp~©Wz—h®q„­f¼Ñ|‚¨Tt“ƒ’°…¹gƒ¨ZlYx˜dw’VrLm„D\Fh…S‘µ~‘©u±Æ¦îÿ¡±Ó…ªÄf^„S‘¬}–ÀU[A_ˆI‹¨k”·…¥ÁnVq>TnQ|¤¶â’¸ñ·Ïû¤·ã“™¸r‘ÈYlžT´a–¿dr™Rx¡mœÅ…ªÉma?j‘ƒ±Zt“K{žPq™Gb„L{¡c¤c‚¨f€Ÿb{’Zx•t–Ám“¯PnHgV|ªgˆÁ|žÎœ±ÚŠ”Áf€œ_‰™Ww—Yr¤_|®^^{U`†h‡°x«^t’O\m@YuJ_z:Rq8[xJgƒLg‚Fe†RsšQcLZxAXv?RtTfˆo€§w©z~¨g|žZgTo‘_tš\z˜SeŠWrVmŽSlŽCSl@\zOk‚RScUYe8@oC<\EYG*bZ&rmmnAbyI^pI`fChk=j{@p‚Ny‰Va˜ba}efe@yZvyGUŸWM^MI`2SV4K}:Te>ci+Yw7[r=OjFXa=\[7mrGy=fŠHN‡ga^D^]2Zk:dk:ruBoa|‰O¬‡d˜¬lx·„\’yÂhFÿ¯?ÿ~uÿ\1ÿf ÿl ÿx)ÿOÓV\cZ(jh5H„IL\8[`'j}E›„Mƒ©8~®ax±`A¨Y&]H05#Q6Wk*^y>ar9VFdvG]y.o|4U†=Ko@zc.f|?pNI‰dRf?Hp9pi.Y€;{whb‘`‰]¢ž[É”Œ°w}²mq¬]iwExxU‘ŽN¼\—Ïw‰ÔŠ›«}€ÓЧw”¸rk½d]w\u…HT•eYnQ@r=lO9}Aƒ“O[«c{4–²>‚žu§bdšPmuCƒDj­ˆj~g§}=½ƒp‚–mUÓ\¦¶ýÄs«ç‰Ò©’åđ»pÔfÊ«hŒ¼htw›uA±„\á…Z°­€¦‹S‰…UCo[1:V*M<*1$,BN/'tc-zgL¥ƒLÃÀs„{r}lJOƒ3HX5XS-En-fc!e[8—ŽP„˜S¸ÂJ˦™•Và«TÇÿ”u¶u]–QPrB~Š2šJ\p„~;£ŠH¨¬xp€D€7ƒ¢JtŸRw=›M›c¢œV¸·Zµç‡“Ä_¦§g’¥Vp˜F~~A¤§JŽÄf‚›Vu¨Ž©Š€±ó•—Ãva‹nX™Afˆ,e‡6uŠ+±¯Fš©d«ãªçpsÄt_ct®µ3{Ö2‘1Ú¿^Áû¨¼è»x˜~¶¬V傪«wŽÜ„ˆ‡>p™oEp†4BA\Q>̘_ÓÁ•£ ¥ÄÉñm’¤€^ŸFbxCO{7otSfˆSŒe£¾|‘Ï ÌZº¥ˆx¦yµªXÊ`‘¢B•—€£Ÿq“½u{‚RѰ”Êvvd¾˜j€æf‡yS†xTl¸Tž3jzN®“T±©[‹MÍÐq‹­zv²eH^&fr0ŠiÆÑ–Ýï®Íôˆÿÿ¸ÿÿÿÖÿ¶ÀÂÕáŸÒ‡žÏhܯQá¹…—±†ÐÊ›Á쀔ÂMƒªIž®boKe‰9p„RrWÉÀe·|”µc·ÏiãÿÙÝþëýƨå~¨Èp§–LzŒDr²5Fp!•¢Y¯Ô¥Ò€§Íc´Ó”Áع›ì‚„œgs—`ŠtœÇ™™¼j† ƒ‹©|¶ËtÔíªÖÿ–«ç‚¹XTlFW_E[f3ˆŸE…žI‹£`o˜Dœ¦R|R‹ cv¥†v©[›™k ¾sl…Ko‡`W“PZp8t‘h¯bˆ“jŽŸi_–7z—d}¨e‡²sq ƒew`r¥`Š·{‹ÅmgžE†œZd~PawFo’T~ zp˜SSh7^pLaZmˆh†°d^Bx‹Y|¢vްr†¥€ŽÃtt¤Gz“VªPvšQ\yHe‹?c‡2Sw=^‚BeŒH„¥`nŒOivf“CnœK‚±Wv‘U‚šeš¿^n“ty•VXyNp¬\•¹vš¾u¥Xm‚gh”XZ€hŽ”tœ¡d¡e|–Z‘œH˜¥g…–Wx™dk„Z€šhƒ¥“Œ±|vŸjеcv™bµÌ“°Sb„H_…HiTdŠL^zJb‡4c˜Fu®{®Û±±Ö…„­†Œ£t‚PxšKˆ®Mn PU}@MvLy”U{’\{–TqVk‹^”Y[{BPlKSs?QrJ]sT[sa‚”]vRizKƒ˜kª±q’¹]|”Cf…e§ÃŠ•Ñ‡—É™£Ñ•›¼s‚¥hŒ eˆ¥^ƒ£aƒ¤H`xJf…j{Žsw•VWxI_qD^|Zs”Ol…LcƒSošd~«s‰²t¥Æož½Tq—Nl‡D`vARsPa…ceŒp„·Ž¯Ïq…£Ysˆbl‡Yf’UeˆSd†Nh…Vq”L\s?`pJv{Id[\{IKwNUcI`d2wr.vtGlyMoKŒˆNw¢]i“dusVm|Dx_˜‘[w°fqmwPYqMiTD\X=M^–lO[USX*e]3ds=}r?„lNŸ„^  [¹´p«µŽf¬˜³|lÿ’PÿmXÿc)ÿf"ÿb!ÿr)ÿ‡N‰^Wpr.‡j;l¬W`wTdq4w‚By›Wˆ”W–Ÿot¾un›gPž]]gFyi$“Eo›_l†beˆJJƒGuq6r‘5HˆN7X?DQ%QX)Ok5SrErd:qX'nAu—J_ŠNUuDbnJ‡„<Š­€ªŒepNf>f@mP$Š=˜ÈuœÉ‚k½š~’{s’rv’eš‘rޤ‡¨¯qiÅjQ‡VmZIs|ITMwlCzžNi”JÁƒGs­Nx˜r‰—c†‡l”J€™\Syw{[;`4deMšcK—›D¦´X´»Ž{ž…²‚m¯¨p¶¦sÂ’i´šS¸±{°Í—½´uì¦Z·šbÐf¼°p×£Rm‚y[d¦3~³mo£RwˆFzw3xŽCTqMta-§¢OªµuI–{AV@OYSr'|~)JŠ=wY&l|Hm†M€aˆu‰f¼~V–â™™‰µ^—eË“N†ÙufŠEœ8]ź“zÙ©š´IÁÌ]—¸eƒ¤W‡‘Jy©NÂ¥Pž»ˆl™l¦iQÿ¤S¯ÿ°“­nd€N¦|Cf­‘fc?ŽÂ=ŸÇ”t°|gx[y‚2™[‚½fqš]ŠRɱZž¶hµÃ–ÚÿÀ„ÿ»¸”Lõÿ˜ªÿÃw´[•¦LµÅq·¬Ê’Nòÿ£Žòšd¹WbfXlqk NP`+{U=}ƒLo«E|^B‚‘R”A™Ž]œ¢d÷§jëØ²®»z¿±jšË_–ŸX—ÇY…­ZÏ»ˆãß´ÿõ»ÿÿÿ£þ¯µ³x¡ÇŒˆ¨t–¥‰ž²[–¡M¤»`‘°{¡—Ž‹˜v›£‚„¡m›“`ƒšSƒ¢[¢ÉkªÕtޝ`Ž¥›Ño“»o¤«’“º‡¯S•}GÇÁ_¢ßq•µl†ÄmŸ¯ÏÿÑœ”q”’„›‘…—vi…Xgm6n—:h‹H¦r‘¼uy©Yi}KrhdzRº¿¶‡®‹Rh2\{&Xj2ep+‡uL†G……VkKjLv€@y¡aPg@Om,Fb>_oI†œd_‡KyˆP²´ˆ Ä|”­~cw¬O_@n„b—±]޵fv¦Nx˜Mc˜C[‚Fo^›RZŒDi“KnH´v¤³o•ºXyÀD[ŠNe†YmžYiŠ[e8Lw?WqD€™_j|Hv~R€“[Š«T~±jk•4Qt0T{=RŒ,Ou/Dg0PqMQjOPm{~W’r€au‡gr–Vz“iv”Vb}Dk{UZoguˆ_x•X|™gi”VbXŒ”hlCZs?Pq8[|Jj“Rt–OlS}±fz²a¡{«Ä‰”»b_}GDh0JwB~ Rq˜2Yˆ5[„Gn‚AexG†Ok–Rf‹JY„Vt›e‹´b†§GY€:Rk7FfAZTrƒNrŒYm~RlsKXnQiˆ>Z|`€”ƒ‹­‰Œ¶Š‰­plbfŒYk…Tj€RrUe~EZmMl„^[XjLb…A_v=azU‡•`‹PizLi‘cy›iq—n—w‹¨dx[o–Zj†;FhNoEpO7œ1x±Wt‰p>ˆ^RLEki.…yC²˜T†ËfQ®”‚bj‡‰7udˆ†gm‰SW~MQnDde6„rA}‹OY—hRsl[hAtf5i€AqvNnLˆsQ‚`^šlPswa[WÏhUÿ‡Cÿe9ÿ]!ÿ^%ÿhÿt,°vQ_uP`rEˆS0„Jc¤iƒƒM¦NrŸ_tŸby™Xa©l–`†¦U…œj—IŠ´bz­dUˆkZnM_v>R|CSn=:j<5L5GK)I_%MZ5Vl9ssAn‚3€“Bq¥aAd`[=hkC@CI^UˆVUuSMŒe4r:MYwy5r©b?`KXOgv>uPC…CTVGg=z¦i”{Lªy=WCK+_­Mhc“St–^‚T–”SY“bKiKMQPT@3}K5lcHgc7M]@dI,ƒn6‰yAgZŠ~R‹|U—‹R´²e×¾_贀ʒuÜ®t«í–´¥gÜiÇa¤ljõ¡h³Ç† }]|}_•aZ±uLVU¡`Q¯»f›¿t}…nŒf0}¼Oa][n|­©meÄ„vˆN~™6‰Ž8c\ÛŸRz±h£S‘”mg¥~ƒAÓ˜Žªÿä‹®R»ÒstÑ‚‰žJ®K~~KÄT›ÅKˆÅyµ‡k¥áÿóe¦ÿŸ²¶W¼×s¸ÎzªÂmå Põɧ¥Õ‰­n»ž^¹Óy¾í¢e‰\…Hƒ·Ll‰?ŒyR“s¼Ö€u¨x˜ŠP¦çˆ€rI¨ŠL•¯cιdžÈˆÒÝÚŸk’¡cT~5ydK›¢‹›ŒF›Ty‘W±ªT©Ÿw¯¶~›£]Ê»dÇæ£øç„ÿÿ³Îý••ÔʱsÎð t£u´¿‚Æ]·ñ¨á£`ŸF†wR•Œ™m•¥h‘žX°Î|•¿gQfNƒsI²š^mœARŠ?Q^*Ž€M¤¸p”´k§³ƒwÊdl‚rƒHc…Ow‚Q|ƒYs™[oœQvŸJi~Fz‡Jo}A\{Ig{>WzLeKYwO}Yj‚7Nr1Oj/Qn3W}G`†K^‡_vq™«i‰«i‹¦…‹§gše{ŸMhEu‡G|KsOtR’’Ds„Nx—_x¥ZjŒLhŠ]‹¦x‚¢ij‰R\yFk–Rn—JwˆT”Z€—Vw•DlŠ9Zp:\nD^w;SyUjbn‘^ZˆQd‚CX~Pn…Oh‡Qk‰Pl‚Ne}V‹¥y¡ºƒºá‚«ÒZqBiƒNp€Th}FXmEk}Zz{EMY?AXHViL[x]nŸdyžD[v3PoIc~ZjŠ|w¡—¢¼`lŽCb|PdƒJcwG^InvAUxL`yTv„Fk‹JFjIa]Glk:€‚Dh“YW…`Hw\\gJcoJpx[‚kVUm«ij‘hl„Z†{Z€§]_©”etfwGcnChs?uxG¨vB¸Mv¸u–ˆn‡¬Tr•gp„JrBÉ V Ðuc±¡~na‚v>„rRž‡T’¬Uo«h]_ulG`z7pr@zvVtˆdt‡`”„Gz\zmrjOolG^vOF{MHdKbU-ÿ^*ÿ”=ÿ[6ÿ]ÿ`!ÿb"|m+Š€Ef¢M:XN:-`Z%eˆ`†‡O ¡U“¾qŽÉœ¶tr²fd”g~yH›ŒOµfv§nq‡`Ye\vMcq'S~J\d?av+XnvD}€XŸ©V´Ï…”¯€øÔžîŠ‚„O‡Lÿ®m©Vp„PYo-}•Se…?…xR“‰‘€µ}wW†£Y‘³a€³X„™R‚°g¼ž™œ×Œ®º~¬±O°ÉdÇöª\ŠGŸd »k¢r‰Vÿß±ßÿ°“šcÌÈ™ßazzR‡ËZl¯XW8h{+l£1pŽ;„„Apr6„wU^^^{NyŽKTyKŽ»cyŠ?w“<`r@`xB\ƒAHwJPoJQ}GdvZtXq LZ{xXPN4OP-dg+g-fyLvr;Š7l—K]oKgqFa‡O‹N}qQw’Qƒ–T„“Xƒ—fƒ{B…w/—–^‚\È„ƒ»byŠcŠvQcŒFgoCnIœ¼XÖ¢eâ»b}¼t™wµ‚zÔ‘a©Ed}6wwJÿ»yéÿÿ™Õ“z—H´­s‡Ä…e‘‘Nq‡e‚QβY©{³ÑlÜÿÕ“±w{¤Xc~1y 6\`å¥nf«—‰ŽF™¤W¸Ô…«Ñ_ˆ·Xv“S™Ÿ\¯¾ib‘V„~F¯¨€žÁi’§i½S˜žV™Õ}ƒ‹Hž¦Y»ÐjÞòÍçd­Ça“™V­©oÒúº¥õ}¥²]Æ‘¡§á´x•Xq‡NeƒF›¦hÄÑ·§ã§n”k‚UœË†‘•i¦Í}‹¼d‘“}·»¡Ùê­îˆÌÍtÖ—]Äð„q=“|E~˜B¯¬\Œ¦Y|ž<–W†‡O®½vÏïÜoŒŠy­9}›b†žBuK¼Ž|äÜɯϔ¡‚]€<^}5{ŒQŒ­HЏ`L‚7j‡Þþ©€Íe…”kš¦zœË†yœ]£Èt‰Ìp‰¤„—¶p…–cqS¬Z¾Ñ`§ñ[ƒ•Iq{AŠˆi›^f7jŠ;„¢Huu[h‚Qj|`°®y¹Óªºô”›Ætƒ¾Vy‹X¸L“±c¡×y®Þ“¡åhÂq·Wk–\uP”ÁP‡¿N\vDh‚Li–Ec‘DU~8`{NoY”~š¶yt‡_f“OawHp}AW,Im?YfWz¦es¨LCq65P.=Q<[rZu‘CFl-C`)Fc+Db>PsLGgR€±sƒ²dsŠFsOjŒ\¢·–xŸNq‚Ke„=e’=j–D_ŒJf‡MtŸYvzHYmB‡£]`ƒVvAGiD [6ÿ‚5ÿ^2ÿX%•Q#Q\%jd5uvF`ˆaGxpŸ]&‚³?”¨ƒÅ¢Ywñ‚z•ƒ£¡a°Åh™Ëˆf»kN†UVZ'po&‰˜;v§a“Y~¤Do˜Xg‚^†uQy I|jŒLtž]„«X~žPŽ‹Tw¨OYŠac\C”w=R¦cŽc+Œr,œ¤C©Ïm•ݘ€µzkšYz“Hj•Kp—T¿ŽX×ào‘ö§‹²~Œ¬f¡P¸Z žX‘©|Œ­av¢esGŽˆL‹xW›ŸMƒªr¸–]ÿ¾zz¿»È›7ª¥c«ŽXŸœZ·uPœŠt~…X‚{G˜œkw…eyˆ]‘ŽHâ®XÕçrÿÌx¹Âxå’kÛóŽås™‹k¼˜TÅ£\ß§b²î«ž~lW{h@„–M®­`f»šJM_L-u‚DŒ›L]¸G‰|.ÿžUˆÿµz±f~9 ©Zi±mŠY=}¸A_z_G†R0]*LI"­yB̉}”²]¡l„u<‰ŽK|§c˜ŒC¨k—™nPž‘uYYo =PfA~k.ˆyJ•yQ±‰Z݇p –‡»²py¸~š•O»ÓFŽÃ…¯gn“ZzŽubŒj™˜?tž‘Ÿ¯TžÕ„ƒ­i©É‡ïÝ‚àÿÈ|ÌœŸ¤W·Û|«Ä¯“Ç}Q‹Iq\#ThT[Tâ[[yCZtN¯;€»q ªa~£Gs“K˜©T«³p–¥q„ŸGluW‰†Vx‰kªV~‚OjŽW…Dj¬IeˆDœ²pȦWž¦i£¨L©O£ž[ˆžgŠºŠ‰‰R‡§pÛÕ‘Ò_‡žKŒ”f‰²aŒ©R ™`šœ€µŠ…¦]¨£’¨§‘›­§c ­ˆ–ž]„¨_ z»éÀªØu‘ªoo|\œ¥V“¦g…¥eRtZ\qtjfW‹’U¼»]€øŒ}@çÔ¡­ò„ÈØpœÞ„ÊÊžäÿ­¿gʨ\Ç»”­Ðz¼ël¥¬i¯­‹‰¬{™†\¢¹T~š[©˜\v ]Œ’g©Ö{s—Lhz;w|Eœ¤{‹­„ikOWk7mŒWŒ„>šÉR§b„‘{žÌ~{·J¶Ín»ô}‹Æ\u qš[Ô]]…L¯±¢†¥Y²ÊpÝú»Áý¯¡×‹²è‰›æx›c‹ÂVŠP¬¼l„–dwZb…CVd:\i1ƒ“Wsu@skX¬«¬¢ØŠ˜ºƒ•À…•ÄŒžÆƒ©Ì‚‡¬u™ºz–¾ƒ ²z|¡W Ì}§ío{¼hzPk™LŸX{¢?c‘=hŽOh‹_nŽ]‚ŸntŽWJe?rGGr4Om>^xJvdŽªld”ZF_-E`#=L3Ga.Mb9Vl8Jo(A\0Nj;^{CY‹Uckn‰_hyO‹ž`ƒ±aŽÂ‚ˆ­]w“n˜¼~¬Èx…ªL_DMhAx˜_®]ƒ­Ehz@n„FŽ‹r“°„…ªoj‚Gy‚MuœV¤ÐqžÈi—Á[n£^ºkr¨[‚¢`’LkŠIa„I”¢[„–Zz•FeŠOn˜T[}3Ks=]wLexYg=Td:`m>{w@„–N†«eo£pnŽi‘‚LŒŽLd™fopX\q?ntC‹€O†¤Pk„XYi^{fFxy4]…PVl@€c.ÿ€9ÿm:ÿZ nR#Az3C]8A`(GS.8g=9M/G94cQO+jo"i€@«ƒcªÉeoàŠv—yŽ–]—´oªÁ—~ÃzJ¤ŽmjQy“3‚F•«hËqx\QlZlRpq6’E“›l‘°fž­y€Àor–o}X€žWupgro?†…— ]š¬e}a†tQ„]o‰njmHjp:qzGoqS‚“E~šI}–ˆ°—YÏ¢XÖãhÌÿ…ïÁ…¡Ï¦¬µlo¡ƒ‚‚BΡbºæ؃˜¡d”ªFÙÄPÛœ¾fKxWtt1ŠM„m™¤>Ì£g‡°™‡¸m£…[¹Ès´s‹ŸF†¥|g¡goˆFg\Y‹Eƒ€)Ÿš\­›[´‹†™=žPœ²O©[†³o_qRn–Bˆ§AA•k:> q_!‰–\Õ»`—«Z«f?ŽmÉÖ~šv¬¡^ݺ“Êå®»ä—g¯†Mt9h€A\–:€€Ba¡_³Eµê‚‚˜­‰ÆsŸšTÝÅ}§ÓœŸaö¡S’¯l™£O—ºZ¹–`̯c§ÿ¨ª¡O­Ó]ËʼÄݾq‹h„›U€’Yˆ=¡°‰Ã«Vºrž Y~¨Q}’\~¢RbŠ9Vu#Rr5V{=pnt Ld{Hq„NMlWjsgfzaœ¹¤¿‘¯Úms V…±YW‚2dzÏÄÑÿÿ´ˆ³Ns’d­§Ž±Ã…›°xޝo¤¾xžÈ{ŸÂƒ’¾‚›Ç…–¼†š½u‚¨iŸ¨gŒµYy²I]ŒI`xEVzJ[ˆQyª{нic…:XrM[jBYf<^w6f}Ck{G[qc‰Ko~JuˆKsŽV‡}Q]ŽKGl]NY<_^*et0WƒF]xGdt;i‚D_zGcs=jy‡[lžJkfJ}’YU}]}GWpKWv?csAl„XWsYJgZ^YEVk9m…Dj‘QÁec†1Uz0MwHb‰L`o=Ml/>V4Ea3[jJmyNYy59Y$AT8K_5E`/Lf*K_*V€.b¢3fœ8TwJvs‡ªZDs'La.\vAo›nаnr¡Va†Y–«¿¾l_nGTnns‘¯¨Â‹€µnˆ¶t}®|¬Új˜Ìo„³sˆ£en\r“fyŸkq”`ziu£r}§|†Â|‡¶m}³JeŒKq™Js z’¦Š£È‚“¸cd„8JU)BW5Sk@c„Igƒ=h{DX}3OmI[xF{ƒV”Ÿ]¬Uyƒ[Œ…W‹q’¸{ŽªYupBvsDno™`†¢g¥œx¡ iµ®a‘Ïpk¼}Z–qFv`RYMdV2Z‰:YsV`iF_vCttGfyJS…n`cIfk7dx4W~ChrNev>k‰LsˆVn—Y…‰VvNxYl{Rj‡bl|Tt…Sg—XWY_uOmy;y{J$?M8RS4ii&rƒ;‹ŽE·›NÿªRÈb7ba)Yw7Gs1A^)NX$Tb%Ol*RT,Wg)ksK;ŒjcGX€`5¯–OºkY»FliPVzƒUIfaÂDKÕÀoÊÕº“ܲr²¥{—N„›jg¤i]xPƒqI¢@t£„ž£`‹¬[uœ^lŠN{{C¦•A‡¢O‡®O€Œa¢–W£ºt™»y·¤k­£f³¨i¡p˜–\—…S²¬Y§Ëm”Ïy|º}±oKt›Y´{=¥—C½»d˜»jtžQ|–hmY’‡Wƒ¬x’dƒ„N¶«`ÒÜo‰Øºzu‘w©•†žLÓ¦\±·eŠ”of™¥n‹™Y‡¬SŠ\­¸d—¿s™µfjšom~KgnNŒJ{Âptygw‘Kf{O ¨K“Í|x“jš›P~·u†œi‚Àn‰¸j†¹Z…Ÿnu¥^ª†G•¼m¸·N®Ù|£»¦y<¢ROD D{&sl-å¨Wôô¯°Ò½ïˆkÙ ¡Œ?¡µI´`„ŠYMyZqd3ft7‰¤[i \Y{Ej…N}”Dk—cr‘cv•S8†IyK Ûd»ÙŸ¹Ì|¬ó{¾‹ÅÂ\†½…¢C¸¿fˆÍªxšcš¢u¤¡c«­p§³l—™e~–WŸ‡OË¥k—¨Š™¡|u–Z˜?pŠNxi9fƒPooDoƒi“†`«Á„¤Òj”¥c·°…¸¢sª¼m§¨hÿ¶qîÿ¶©Áv©År‡ºh…en—Yt‚Ng{F—€P®xgŹxÛo—å¯fŒ/•“_mŠ^Œ¢_—£w‹Hµ”ƒ±ÇqÞ½œ‘¨h\ŠŠB~žMršP‘GžTw–D¢¬e¹Y`n7c1Z1mKˆŽY¤eŸ·`žºLÓÚ²³ò¨v¿lƒ¸j§‡NºÕuz•[Œ—EºéY¡ézŠ•Gš–eŠ¥o}]|\YƒIR^2LL xa7¨™^gš2exIUx.€‹8j”NwY|º«v¨¿G¶Õ{Íí­Õä—oÄGSuCw™;i‡4ŠIìµ—öÁ†Ç±„iz~††™_§±|º¼w_~N{L~©Z’œn±Û|¥à‡–»g›·j…»\ŒÂNƒ¿N†˜N‡‘O†‹O~‚h˜Š€£±r;e€HiJ“‹_esFVt=Q‚%c—4“ÉY’Üb^’?Y|8c…CapRz]ˆ³€z¦md‹ro’lr•]a‹c~¢x‡¡[]‡Yr’fUgMYnBTr6Om4[nTƒZ„›Vo‚PTtGe~Sj„U|—k¬¹|—ŸUŠ‘czšh’®‚¡ÄްRstL‚}SŽGjmBbqS_sKctWƒ{]ŠŠkšsЧz€§mr›M[zSw£o’¯h‚±n~ž[w‘bœfŸ¥]¤w‘±niŠXƒ¨jˆ¶n‰¬Zi”Uu¤sŸ·}—Èpt^mŽdnh|•bn‰@H_2A`CUt\l‘[r•[h’et™u’¼‚¶Îk§Nb~SeXl‚^h‚Qj‡\z§k«d‚Rd[pƒhr‹m‡©b‰¡RdzWIYc€KjƒC{†J†•^ˆ¯q—m“£aвnj®„d†uOtMh]Coq3aŒA]s[ggBhs8iyH}zL~‡MqƒRdE\€C\}Lcx?n‚:~™O˜[qš^r“iq€N€}QtLr|Y}ˆM†‘M\¤PY}aicDz{C…†B¢›Xr¹ks•ulr5RƒHrr7qw3ˆE¦ŽS¤_ÿ­kpzKLq39k20D31?/^Adv$Eƒ=VN4Ch$U\>8h7?G/eOr* ž^jµzJ‡a_[.†o,™—6iŸV\{_dn?En=}PL~ƒ`h ‚]|}s‚H‚‚Gj©M†‹VÉ£MŠ«Wb¯Ag†K…ˆl‰Z€¡Czd‚…QŸ…L¥Ýnn–ŠˆzKu£qU€ZžC´ˆ¶l’|dŠÉ€q¨\œ}G³WŒ«Uy£_†¬TÈ¥J¤òr¿¶LÉïŸñcƒ¦Wt·h{T¡­LƒÂ`­Xÿ§K¢º§M¥­Jÿ®@tÙlM|–?s›A¡;‹™Rµf†˜Xp‘LuƒR £bµÌaŸ£«ÃŠ–¹…Å·oÆãwŽ¿‚§­u…Ϻ™wD—Àj¤Æh”à„‘–I€ŽQzBæ³eÁÿ¦—ч‰¥f Žc¤vŽF´¤B³¼c}ÂV¥E­©eÄæ¿ÃÚ–Á¥lİw¸µn¸×€ñÒmüÿêϿ…{O¥Ãf ”a®¤U{ÅT]u6‚y5ž•Z‡šG–šk“ƒZ¥Ê€œÄVË£S´ƒ³S´¹Tš³]žÍ”˜h¾çtÄ_‘»Q‚™T»o‰Çkg™NrnY“°d“¦Ww¬}€u0µ­c­ÉŠ©H»¨o ÀskžZD·—b¹ð¬¬è‹Y˜RˆBÄå¤s®S¢{€Å²¸§Íç¯[›ù…^q1e€Bwsb¥x ¬_QŒ2GV aZ3_‰9Rˆ2j\Iëÿ¦¤òƒ¦l;¬•V¨€„b^[~‘p•œ„h”\dnQº¹nw­UŽŽl™´t–ÉYIi=:O&DK5yŠay­Vg˜Np—Dlp>xž[Œ¿tx±iolT£™xÔ¦hÒ®h¿º†¤žƒˆŒX€ƒLv†J ‰Qf…1v{JgAsžH‚µY˜±jŒ§D{•N•Ás¤Òv¸îŠ­f^|DUuEg„Nh‡4Wi:NV3Rb2Nf4yZŒÂr…ÆcˆÀgn©SwŒU`:Mx.Rw;`‡FYƒ;e}Jwœ^w–_X}7eŠQƒ¬UXACfUzk£Q\vSuŠ`‚«pXzUSz@Zt]“IeSs=h”D\\}pN”C€¬U~ªqt™ok“^mŒfc‰^[zURpIn_:†2j›Wh}btvN„ƒHk–afyfvuRyRy„M~ŠQ“O~„JŽžLq²[i™jl[g‘azuP„K‰~QzXm‚Ot‚S]ŠIJzT]b3ww:tz=›‚R¬–^ŒÈ¢›nj´kV„jYh9rpG…‘Bƒ¨`„¢ft‹Is‘CA“K$YH<<"Kv-\ŽSGCS_,Iy3I]4KR(d^&Pn/X]?eqWz‹`H˜T?NNCJ3lZBrgCN–AƒÉZx–kvžP‡¨IšŒLŠËju¡sš¯R³beŸ]e~In‚=K›ˆjx­g—’^ª™K¡um˜TU“¸d©€‘Ä…©»zÝïvzÿªÍƒ‚ãÉj•Æ™w€ºle¤K{•?w¥Vj™|„ŽQާo Ã`m±ƒb¦]Ε;—÷²Êi–Û•[¨e^l/”t/q”h—ˆdŸŸ€¸ƒl–_ŽŽj{©x‚ztp¤]noKx“A¡©Wk­rKØÐ?që­Ž’fƒÈ\}²uSrNTl8io;Wi8ih2`vc{`J‡‚K®«`„Äu–½R„¡[sŸ€y¦J—¢?“ÀŠ}¶‚“N„_Ɉm¨»vb›mˆm'µšSʵ„­“{Ÿ—r¡fݸ^­ø›ÀµK´ÿj»ÅežÕk»ßjj°ie‡?”§GÈ]y£r‘´^¶²`™Æv‡Š`w˜Qº~RŒÍ‚…du¸‹D¤ÃR᪇äáÊzÔ‚˜DÒ™[³ÿ±½Ì ò„uŠ@yG§¢L×£_®ÏpôÍqõܬŒÿ°¿†KÞþµ«ë˜—¤JŠ—NŸŒXºÚ’}©:ËÁxÌÜÿÿ¡ø‘Èdÿÿ~™Ú|ÚÿS’ÓOõèuéÿÃÅ÷‰¡ñn­½ŽØÚ¢‰®jÒ¦`©­€}šaŒ€_–ž˜UŽ=bkJ–¢j‰pƒ“WfeTµ—x«s:K)y‚<‘‹sƒpr¶E†‡U“aµ™VÊÿˆžÊQ«Âwœ°`»é‘»ú§œÚn™„u]² ‚kŸZc}9‹“[Z‹7—‹d„½xpƒE‡°L—¯Z’’]Lr5AL XO.voD¨Íi„àaV€#ÈÄ«¨øx—6¢šW‚gDˆª[b†GŽ‹Y‡¦3©§g¦Ç€ÒÏ”q»L·¶wÚÿƒÕTs¯5=€%moUšÝ€„¨gtE‹™Yœ¶”±r^…LižLgkX‹ŒrÕß|•åX€L’gv‡J˜£aÈÜþÿª¸ëf„—QnA˜³|©Ù„±Êq»À®àûžÁìŸ~±blŠMcˆCTl5JT1Yw:Uj1Jb-\lE€¹V~§b†s„­xo’R`xATq7\z==S*Hp7n_“Âcƒ¡`©Ya‚Bm‹A{Ÿl„¯kr¡Mz¯V…¹U}ÃXj¥Mt†Ëß™q–K]s:Qk(Rl>‚ bv¥Md}V‰©i‰®ƒ“¿s‹¹doœa}£n]‹=tˆL`„=`‡VeV\zMg|9`‰Rвh…³jw™[ržimžaSzGTr\c€RZ}OEu85R6[v[‚´Np\x·i€¿Y„³Z€‹XxyS‘vJec=WiENcFYqgYs_b~kq™Xaya›vœXt‚]w–W^{Qw”a£h¥žgŽ˜c‘—Y„Hn‰KhƒOj‰Pi‚Hy›]o“K^S`„WiŒ\„—i•˜m‚‰NhxU’—^…¨w–¸‡¬Û’·ØƒœÆhl—NXzTzdlŒMe…d†·u†¥RM^4BqDZ‚OvRm€@Xq;GoEf’g‚´kгv{–gpObsZgƒplŒ\lŠTm‘\}†VdtPm’ftžos¡x­cy˜O|‘S‰Ÿf’¬e€†Lf|CVlAejT[u8jo;f„Fnˆ\‰…VYœUS}umhN‹€<ЍYu³rc’nOŒbOmO\b>Sv:Qx6‚i-Œ2s¦`v„jo‰a–~Y„¦lrƒ€c€WyjKsv>ŠyO{†VŠY‡œXm¤^m€c\ˆRoR}wLtƒPuƒTh„Jh†Kd~Qg@qƒFvEuˆFp{I…|E‘‚Spµw•mr™`q•q]yD†rJ£?x³da’rZlLvt>{H|Ÿ\`¢H†s?{§O…›QmªU‡Oc²IWŒ]yo.ž…-†¶Lv®U‡K“PG‰k?A[g;Gf$‰Y+Y§B/kaF<(lIqˆ3¡h…³mè¡l¦Ì|h¶®y|ˆ–a¡®x’¾z²”q©ttkUkm[¥kK»£RŸÏt¶ow±n_…KxpA{ŽEo—c•‹GÁ¼QŽê„b½„‡}Sx¨WrŽMZt`e`†9„‘`m|R]“Ghƒ<|‡OÃJ½à‚ƒÇvwšYxzN§@ÚŠÊi˜¸~¾p…󫅜ɳÉ^®Ûpv¼ˆ±¤HŸÐ„uªw_¯h›£j}Ùyœ®[…¶T¶»\‡ßŒÒ¨_¼Ì­—°ŸÑ¤“ŠÓ¡tª^sRC†VGW0^e }{;‚•V~¿T£·U™Íesµ_z¥Wi‘O—€Oo¹uÀ‘D¨ÿ‹ˆ¼£Ã·|Ž¿–œ§”¦v_«w=ƒ˜Bfzf\Š0^k1oŠ9…uFÿ›I“ÿ—}™L{‹5ÓªS±øˆŽÎ—•½†tt€c8‰[L¡‰UȼU­x¨‚T—¢hµWÿÄmÿÿ›ÜÿÊäü´ÀÿœØŒ}Žz¹·JÒí’­ÿtÿÿ]ÿÿМÿº¸}°Ù…–ÍŠœ³eÍ£RjÃ\{x/q—O’Tq¨r{J–™U—wù©ycÿ¹jƒ-Ûº=ŠÀ¦—›[›»›»W—Ïq³·`¸¬…ÂÊ‚ÜÌ“„ºh™£cŬ[¾Â„¬Ð‰ÇЉÀl¯¡^ÿÂÿÿܱÐj…Sg•8b±»NÿÿÔâÿì–¸Óב¿†¾½—Á®˜“Ô™Š¨cøµk}¾‰™†kÛži‘¡\ÖÍe½Öxy}]v¢DvF|‚H†S†N¶ÃUàÔŠ‰ðXrwK‡«7‚¨kn‰V…ŒPª¾]~ey´Å˜£Ý¢´R’©gs“_©ƒ‚›a’eL–¤Gƒ¡N„‰fkojŸ|U¡wmq“;ˆ‹Q¸Êƒ×ÿš‰­yuG•ÎN`ª2WC"mDLß±ØÄÝÕ˜µL£Ï|¶ÖŒ…ª‚—x^¥Âƒnvvka‚dÕ©o§¯§°ƒÓ롟ÑnÀÁŠîÿʋĉ Êwx¸NpIWwI€¦;j–>‰­V~ž_v¡g—žu•¯…x·R{–c­Àœ¡v€T‹cïã°°Ë„©¢‘­¦cKb~?cŽHˆ£k¬¼Ÿ¢¿‹§É‰’É‚w´_Fr@YlS{ P[r/d„8f‰>^xNl7DV3YU9_g'Yy8Ÿ|6ZµK5jsIH(TQ%`U0‚r<«Ž`x­UWˆnfjVH¦c’Ÿ_†»p•¨|‚ZxŽU”};mz;‡q>•›Pœ]u•a^ŠRgc;–u2i¥g¤…Gï¢VÕö¢fãÉ^Šubz<[zG`v5|t4pŠBlqL†Sf¼be’_‹’T±©X—²Šu¤kƒYr“Ca‰Ex}PŽ—Yw©sœO®Â…–Ö¤ÂÊ™€æ¡•¥i¢¹}¦½l¡»Š†¹—}©X‘”]Š©lÂÊw¦ö®s¸vZyxTubpZ3pm7jxQ”o9à—^‰Æ«œœ[{Àqm–Ru6~“HÞ¹LÎÿ¬Ïñ¯ïÿ¦èÿ¾eó½dsV­‡3±÷u°ÁtdŽ™—Zq›q…‰]ÁÐd’Öª²ªt‘Æ€m§Zl|RtaK‰„6‡¥U]™I—‚<«t¥Ïf‚™^ƒ’Cu‰…lŽZu›Uº—EÿÿiÈ僅£vŽšwvŠm…Bÿ„iµÖj~ L—VÀkàÑý«‡™m¶ŸqØýÑÿ¡Øú²ûÿ­ÿÿ­¤ÿ×Ñë`ÁÑ©êáƒÄäg~¹…ΜSxÌyp€G¥qDx¿xm…FuƒGn•>W¨¨€©T}œQr²FtP€©CŽª>†¼i‹†Q€±WŒ…G®£c¦“Më왬ߟ¤QÂÀaðp¤§s ’WÞªqÖÁ³ §ˆÊº‘ѽU„<€M©–m¥Ê­¢`˜\Z€Swf2¢„]sœa——H¨´wq‰cKa(ªvG˜¢Rµg–¶q±Ü—œÎ| Ét¢h«³D¦ãnšËM®­`É}ŒœKi…nq…<{žE¥‡aÉÝ‚”ÖhG{>c/y¯@„¶Q€¨T¤Ýe|ÈOv‰@nz]Wq8a_.gvBGb-Ž]3~{Dÿ¸žÜÿ„fº[ e_qŽ5¶¬©Çò´¸ØŒZuBLG+€‘<Œž]|ªf” _|œO”°\ŠœYuœJq…D†_>Š‹pacIˆ‚a¾Ï¢œÜغßì‹­Ú”ƒn¨­q¦óv¸j€«as»Io„Ra^WeE~™NzifÃ‘Š²U¡µjùù˜ñÿ™Ôuœ·–‚£]t P3a%ZbFSr@j‡Y|¦|w™n]vRj{a®szµkl©CŒ¸v¨Þ‰ŒÉS“Ït¾áßú«žd¨°s‘¸jfZjIv±CqŸAgM}šZŒ¡nj—Nb|i€œyžpªi‘È~ŠÂsˆµh…­[pšco\—_h‡Ih’Pl“Ug‚RhƒTby=Tz5[p?s„WmŒe}ªd~­‚”˜‡‡¬UZzAp’MfŒOzws˜zfŠX~‘HiwLx~]y–€“¼‰¨à“Ètq’Ft—?Rj4H^3=U'7J)D_5;OFavf|šgq—?Kn8FoGw¡qx«]X{Fd…aвgj™a~’rrŒGiŒM‡MZj,>^*F_;Qj>LhFhRai8LjLg‹Uj“Vgc€£q•­tœÏwšÞhx£Su]Ž£j‹¨`l†S_wWn…Uu‡Lt~Hn‰M•|¢Èz›Ôt”³]w˜o‹¬ÁÒµæì˜¡§ez“PœU—H]~Nsnvžfr’MmMbŒfq¨k}­m…±r¥Vc‡DOoDLgfW€•³oЬnƒ¤p~¤r€–V^yG_vHi”Os‰RcuX^alŽ]i”b~¢sбu‡¯±ƒz˜v‹`’^MxEN_=H_0dX6t{Ck_Q‘[^n`ˆm> •>l²Te•_XˆRYwTmmAO9TuCVi=U_;To<‚_J~•Rl¢pc~pNƒYbWV{l5q‚>coFQoBfXˆ@n©GaZvpB«=­¶Z޲s«il‚]‡†;‘–NrŠjbw^[{[vgeŽ“N‹¯[i¯vo•\x¡H‰šP~Ÿg”…D…ŸG‚œRˆ’P‰¨^…´fx¡oŽ“q‘¨Hk‘TjwJz:ŽJ}‰L†|W¢‚D™ÂuÈ‚¨±v•Ȉ}£šŽW³n¦Z¤¬\§ºp»l~~U{kO€‘O„~Jsž?„~K…“c|‰Kƒ‰dŠ£€h¢q\Œ\BDmS-f‹>tM±ŽD³ßZìˆc¬‰€ˆgŽ©Sn˜€€J”§WÔ³\{ì“Tžkbr*M|D{]BƶRœñ†›Ôq‹ÉˆÀ|‡°_|­X±’W“Øz£ÐˆÕw¹¶j´ênƒ½ž‚€e¦³By½tnCyxH]yIunKµ‘HÌÌt‚fMŒQkk:_†7•^F¯¬`§º±Î¬°éÞ¿Ÿöà–¡vy ”r–ÐpŒÐv§j²mj¤T†‹MšŸy¤Ä½¼yx®™”wNN€Qpm6˜©; ÀŒzÂqpœaŽzQ›´^«¾j‰Ïf{œO”P‡’\Æ‹L¥°ƒºµeÁ¾\Ÿ¹]«¤TšÏU†—Or–c‘ŠHu—g‡€^ûქÿµoÝKǹ<Éÿ €ëµ—‰ZÝì„ÿÿÀÅÿÏÄÝŒ›³ƒ¯|€×«lj§h›RНijz_ˆ‰?—Çiƒ»`Æ¥FÎe‹Mt<‹¯hn>š‘Ng¿gt‚Em‹J”ºfy½az‹C¶…nÒÞ§Á£oµ¯¢|Ÿi…“Jؾƒu›g™P””Jž¥cuh}†I]mA\eOYg=y‚6t•Pn‚j~„LYxSˆ‘? Å<«¢q›Ã]ŒU¬±e»¯ig‰Cœ Vˆ¢c§Ñm²Ñsya” j»ìm²ôw¥¿†¢±w¸¶j¨Ñ”}Ò‹tC—Ng„-˜¥RbˆI‚VKÍÛ™àÿ¨™Èkv‘Pv—]n€E†c©Üs ·_—Gm[/fvKvƒP~”7Íñd¡Ëq d~·tq6[œuZ¢„Y«¯f«¦}â㪤¸ˆm-¬¯Dž¾Qx’E{“LeyE`p>ІK×ÉyÙÿzªä`gŠ;NT'ni7s‘LYŽ1Xb:g7o‘Sù’þÿÇ·ë¡Ïò¬–£×⽬ú‚qŠXr R{­TdnO•²p—¼zmˆW†›‚t¨\…FmŠEpŽYfœA]z0Oƒ(@X*byE\v2_™6Gk,Be.?J5†™’À}“Û`†ÊyqŽƒ‡—×ôȳàžl•T|˜a¡ºjr°W‚£pšÈ…”²‡°¶‹¸Ö{}»lŒuyŸ`h‰QZzAcŒWyšmt¦Nlc¡»˜Ãd˜ÁT_…Gc…Ek…UxšTm–Pr X|ŽYƒ—S|žUsžJyœ\k—`YqNtf\œ«qu˜h­´fy—Y\ƒFCj?Z€>\†JxšSp±Yt´am™c~œz| OOhHn…Yf‡Be…>Kv,Tm4_…:@\-2J2AXKlzNcwDctIc|MPhCGaBczfª¨sw~O_xdŸm‡œ\l};Tc2Mf,He5Qj3OkJh‰Wj€BcOdTs˜_‰¡b˜¨n”«s‘ª|¦Í‰“Âo†Ÿb„™k|ZdQv‹a{œb¥Y‰ŽY†°{¼Ó‹³»¯Í“ªZ~”Qt‰c{m~]YsDoŽV‰–atŒ[ªv”¶– q•R\…8[Œ]†³h{¤w{œsrœY^y>Tz@VuOYpi›t‚Ÿry˜`s„]€Mor?`lU‹‹cŽˆNprKs{_pŽeu©kt¢v–®tuwlx“^††RuxWX}LYkDWo?ta;i|{’F|’j…‰D®|C€©^Z}_taueCy„CBKLkYrg9w’@x‚\ŒId§gx…s—XÂcpµznŠv“‰YЏel³uœi¥»q˜Êˆ‰ÇЦ’e—¬qy–ymxib†SutIl“GAv`Œ35®[~º“Ÿ~|¤ov‘wt™Ir†I‹W‡a”‹oq¤_}„K‹zA••U‡©Mk¥Y{ƒK£’Jv¢cmJG¢ªUoׂjŒYy‰7^™A}…J›©B“°j—«|y¿†fkˆ{B‚`™CyÀpm}X„}Uz±onžWX‹Kiz3™–8Ÿ×}´Ü„«õ‰zÔ›s m€ˆgh‡HS~|hW[p„L•va¤×nu³‹otS^‡£=¦Ïš­~’¼Y‹ekcGuˆ8°‰C´l‡]nŠ?h€Y{E`€F^8Y}6{Q‡ÈsÆf_–B^wR£³¸êéмèvÒúªÛÿÁÁ„„Çc}Ÿ[ºê’ÂᢔÉm†¹hk DK_;\w5_u?¼i‡Çp}°e~©džÝt’ÁqmšIGg7M_Dƒ}p[sQi‹ZˆÂYe’Jv‡Rz¤f…¶d¤\qŸcGZwN[pZ˜¬{“Äx˜¼^sŸV`7Gc2LaKy–k’Àb·`p˜FJ_0HY,Nb(Cd4I^0A]0E\5h}Jey8XeBdvRo‰OgLu‘qrŠWIc1?V(Ic7Zw;atM|˜X˜Rˆ–U~¦[€¦eµm³ct…Stƒ\…‡gžm”n~fƒ¤p˜±hs¡_l˜\|˜cmVj‘at™w¿ðºÿÿ¨¯¶w‰›v“µcwŠN^†BZ}Tq–Qh„Nj‰]†–`€ ~œÀ’£qku]n„PqJj_ƒ±{§jn|NYvW]Šey™g‡§|·Ç…¤³}вt…¢g’f”˜WvŠPowYz}Z{„Olk@g`CMfby˜o‘˜h‹XzqSjp`w„]}‹Tx‹PUw>kgDs‚@hŠTY}[asYtmIp”Usœ]W•]RwSbrEQy5WqDMr`‰R_vNoqGdˆEAqVQ92g`,QwZjrP‰„P~›pycs‡N²•L€›H¡™X|§PU”S‡}=“’?—U”£[šœQ©ºcÁÊtˆñ‘©¦jθfð©‘„˜¤“EÕºW§ä}™ÒqzÉs®™b‰Ê‰w°‚–R˜¡Xº_šË…®£fŸ¾a¡Ôsy³€ƒ¤qq£L |^—ÁlÁÆ£¿Þ”QÙ®Q^JRr)R`<_p5?M;^:;¡„5ªÍ}¢Ñƒ‰Ñ€X«sP];ca-o‡7p’B®§O¼É|©ô–rµŽqeB“{>‡¥x‚E›ƒ>Шeа•w’|I†9 V8“Ÿ}´·p¬ÄsÀƒc¥oŒT¥Fͽ|Áì”Æá§lÚ¤}q@`ŠIr‹=¨œh°µb¨Ë‰[˜~biJs}5°©<ˆ£NlE‹†;>‰H¨€P”¬{˜uËÃŒ÷í”ÿæz§m‡˜Lq”eVtKEo-HQdxqz^)csIX€5Jq:fƒcbƒj¦u[|gbveš\[|F{ HkŽ=]eAyŸYo‹QexPcsV}–b|¬Xr¤^‰µ[z¤Z‡½_„¸h¶bvŒM|’\ªÎ…­Ývx²G]~Aj‡Oo~[‰¦tp¤ghŒh‚¢U~´Hu«D[…Sj~hŠabz:Nc1XuCp†N“I[i7FQ.O^JkxVYeGh„VŠŒP^xTy•c|iq—Qp‰E]>iŸd¸o‚¢]x¥q’¤SjƒS„™q•¸r‚¨u|ŽiZtSmŠUwŒ_‘ c€_–·{›»›·p”¤q„£i€‘W޲a©u ¼½à⟲¶hzŽ`€ªavžW Yz t”Æ|б]a„Ok–d„¦Ž­ËŽ˜¹]^sE`say›hyšdƒ¥tŠ^ZlAQwg‚¡z’®}²›¨Øƒš·m‘ªh…®m†¸ƒ¬Ú¿Íw©¡i£†V™‰]‡†B^]8FVHIZQ^bJh^?ebEh}UqzTo€\ˆ—[{†>Š]¢Nj«d[’v\|Z‡i?vœBX«mS€i^jIpy7ZŽ>ZlO@e9?U/PR%Ga)G[kŽ;e“Zt‹KfšY]‘fu{G‘y9™ˆBz›^q•c€M´—TªÇnyФU®€xo@Œ‚4žQÀbƒ¥i«©|xËsj}nlt?Œ|4q“Nw“Fy”Mm§Sn’OlŽbt|Yƒg±™eÅÕ™™ìÁ˜½œœ¸h²N™œLp’Um}Nl’L_{O€q?~F„ŽT™¯Oš¿Uv»pˆˆc¢›Gvªg†R‘—WŽ›N¤¥Q–¾V“«\v•W’‰R¡„SƒµqÂŽq|â–„§|w¡Qi—f›Œ\ž¹B©¹i¢Ü‘­Ã‰¬ÊŠ™ÊŠz´xtlj‚m‡jR† fy¥t}Œ\mvZ[[o‹M†’Pl¤K}ŽO³«@Èš]’|hliaŽKg{/^|4=bFI7#>"•¤B„²m«lh‰bk…Po‡FŒ>²ªJ–Õ|Ít|˜sl¤n…^›‚@šœJš¢c[™el`5w…?€RjˆVqˆQ¬’N±ÏŽ’«›±—h†À“x¢…€h±¬Zÿí¦ÉÿLJ³Æ·¹p”¶o¤‹V©Às Ì‘†·ZdZv‹?¨¾6r¶M}6{}I‡xXž‘e¾¼e£átÇ V’¯™®–_í“¿Õxj¿¬•šOlŠP‰¢Pf”c_”Q[ˆ.U“5…—$œÐSŽÇK‚·ek¢Nk…7¤{=ƒµXf3ŸŠ9y¦uu„P~…M˜¦X°Îm™Ÿ~±¼räÀ|¶Èyª¯k¬½aÏÏ€÷À˜ßˆ|•c©ŸsšŸ ÌÑŠo—w£˜TtŸcœ°W‹¿mt–eƒ©[ËÄWš¥l§Žc‹ŸRy™]Þ\££Yvf~¶[tŒ=ƒ°i‘^¼ªi‡Áz£eŠd•¶i‘™sËÁ„ˆÁ€v‘_{]ƒœc›auƒS‘…]–¶n¡·g†®ai˜OYq@^MX2wŒ.g|/—œLôôœ´ÿÉw•Ow‹{ŽW¶™^´±Oÿ痲äw‡=ÔÌËæÎ™À†¬yvÇP£§sšÑŽs€a•‡JbE~r\“ž‰•g€²r̵i‹Ø‡Tw+]Lž„‡fLÓ¡±´®€Æî“ƒÖmx|DñÓƒpµKj]6†…Ho†@wgE‘|IȽˆ»J­‡Mº¬gÆç“Äﮑ¯Vn|E[kB¤xhæÿ¸­Ç©·m›´e˜ÇY¿U‘Y‡¸L”®‡¹êŸ¬Ìd´éŽÁä©`=„¡Vˆ²SiŒXpRy“}…¤uŠŸpV{U8R<…—€¿Sn“W}”Rw¦Qa†?Rk6lU`’7i–Y•¡˜‹Å}~¢v¿c QyºRyfvjmŠikˆkˆ¡{Xˆ8hœJØzd•AwN†ÆODq'@]*dnOŒo„›c|Ÿ[~·Vh“:i„GEp2@T:}†Ž¢Ê¬É¼Ûek¦9o—K‡¿[mlTY‡FLo:ZƒK[p`xŒw‹‘nŒ¢w›>S]FЇ–§{oŠI‹^r‘WW}Cibx¤nz›hlŽWZxTe…\]zAG[,6I'CS3L^DyzTutZkfDTa8Vk9]iNk~Hr†a”©e©ªjާl¡Ù|›Év}šboŽk…¬uŸÃ”®Ì…Œœb’¢k„šKSn:Qv\w‘d~£`|ša®´}š¾m„ª_uœi‘ e{ˆ\zZmQ\cPcpUw~PfK[…^… iŸ{Ž´„–Æy‚®\®e³`…§lŽžmz—s|žYk™Tbi}›ol’x‚µƒ”¦X`}_­oНn‘¯v—©iˆ›Yy—o£tz©„•Ä‚©¿i¨VkZsŒhu‘~ˆ®”±Æ…†™c‘{c¤Šgƒ”dz›Hi„GdtNs‡Kw}DpyY|’`‚“U|Še„žsmŒPj‹dp‰hb‰bŒme£`w†cp„DK˜h_p^i}?c‰DVˆDQ|RAlBKVuœài§Üx”áqËz–‚A¸®Qv»Œ|=›ŸDžÒz”ŸPÛ±dáÁ{¾ÇqwˆY²{O¹Ç‡Øßq“¥‡àŸ‰¯éÎÞz•£á¤\l>ŒY‚‘T’¢a°‡sª½‡ƒŸSŒ¦Y;nÿÿÙêÿÖÈÿ¬†Í{¤µY¯˜aâè\á’lÉËzˆÁdq„S“ËukšIr 7b|9ap={ˆ5|¼LnƒO|ŒL¤Ár«¹‚kœ?pt9Š˜P¤©^C„xC—pm¥c‹nc¢‰w•µzn¡Z]z7{qH­ÄaÂî|¿ò£ªËv¤ë€­áM©ø…›´LÿáŒóߘšÞ­¡vÓ¨­¬ÓœòØàÿÒ¤Ö•—Åiµy—Ì…yX”tJFÀTŠL¥ÐSáÚ•Äfiˆ?¡ªL Çkœ«qÄÕ‘Å´rš²—¿žh`7¨pUä«“×Ô\³ö{¿±hÓÖ•ªÀo‰Íh¯½oÁÞŽÉü©·â™Š¸g¥L…ÒRU‰=¥†œ™ÚY¢´vÚð¢Ûÿ´µÙ|¯\sŒH›£„Úñ¼Âæ–çÿÐ½ð©—Øbz“fˆ—_‘¨njŠFƒ£oˆ«kk«R–—‚È÷…‰Úl“™Št™f ¶ˆ{³Ku£JZ~:‰›Xi=|‡q‡°s|°bkTp›Mªi¤Ñ‚mLPt:`|8iN€œyx—f…j³y‰­Ye’OW|DL\'_}1Y‘2W5i’An‘Vk¥JyœJ©FQ‚4uŸQt”PRm;«‚_‚sq½Á’¾ln”H£Tx¤b¡V‰µ\‡•DQo2Usq—LYiC^rLVlEn„\Œ˜Iq’Qw¯`jœQR~@U‚Oz VsžGdj<`j?bpDƒµn…Â[sM—vŸ½ˆ®´|¤°ƒ©k~ }‘¨|„¨ln•_o—{ž½‘Ÿµ_sYr„cuŽSd†Nges˜s‚«m‘§op“kp†`o€Wk’c‡œb„„I“[˜Eb†D[€Gm„O‚”V‚˜Nhˆ\{_uŸt‰·¢Èsš©bwŸ]{”r…’PbvDNqQf‡XdŽl®f‚¯tšÀw|’Vn“yŒ¬„Ž­{ nœ‘®wŠŸcsrŠ·‹®×~§ËZ†¨@a~/Ag2<]@JpRY€\‚ŽV‚ub¨•o¬º‡¯ÀlŸYy]z‰`‘‡c‘’k‡¡qƒ¥ht‹am}XsTQŒbbr[aqR¸{QfœNe |ZlM[sCm~Mk‹Bn‹I‚‰YwžVY“ZE{KR[;Zl1Z~7a{EK€LNX@=N.’t=ÿ댗úÈŸZš¥bãÀ–Àù¿¦×©²Í{²¸t”ÐfµÖo©Í•’Å}Ÿ³}¤¯x‡™w—«U±Ü–ŠË]u¢j¯V˱ÿÿáÿÿêèÿÙÿÿµ†ç°w†Tk|8·”f‰¾W]v8s‡:¡W”tŠ@m«^pKrNÌÒƒúÿ»°ý¶}m‘·f—ÌhÝϨ–í lœOž–fè댵ÿ‚‡¶j‡®cŒžh·¸ªŒÆ†”­I´p¢q§Ò}›»nmg8qo2n’C²­‡¦›_¥Âœr…ZHŸ¶o·vcÑÜ©®àŠ›M®‰‹‰žŽ‹p¶Ë•Ë´ùÿ¶Ë·~šº`dˆ?ovA¨©ºÖŒ€´e«Ÿ}ÿÿ½…É[”žX›Ð`T0w‚JËø¬Àá”ÇÒ…åÿ”„»f~zdcuRi‹M¯xi«^atG^q6‘—xœÑ–~ƒS’ŠxÁnv£D]9‚”aŽžv–º”RuHawS”±Š¼ipœN‡“^x¡G™½qØäÃéþïÿÿá¾õŒg•CˆÉU‹¹v–Έ¦×ˆ†¶Z¨Êw©m`•BYm8Jh*7]!F_:[k9Ro2lˆS¹|ªÔ‡¢Ù‘s¹]iŽX©¸y~¯Lju9F^.>T@b„X‚½R¿w¶î¿ÇØ¿½ã¸€mrvsllœ›Qudš¼‡¤Ã€„´h®äzÀÿ—Þÿ¡Ìkt‰Dd}Jq‘Jr—]…ŸLawF^oD\v@ezU‰rƒ­m{©_ƒ½{ŒÅ‚€¯j}œr±tu¦[i|X~‘v©Õ}£Ñ{•·˜Á’µƒt•fy¦dx¢Z_ƒ;]~J¡t˜¡~ˆ£{’¸}‰Çx…»w~­]u \~™s›ÁŒ¤Ú”ŽÅ}x™s‘i‚™T„˜Ty”aŒ o’Ys„QqŒb¡g‰§Œ¯Ø¸âãkg€FHmRi…\|—o¯—­n{NkˆZqŽ[p‹`kŒCTmHZ€q…®•¨âÃÏæ„„ŸQWl6IfIKef~œ®Ëš³Âty‰]p}Rx•h‡A5@./IGNlAY@Z…V®e{”G]o7Yr;T}JaŽPsŸ]•ÁtžÅj ±W|Kj€Sy‰Qn}Hce5^Y3iZ0\rFcvDc€LjiRŽuCHR¨jgy}\„:[qGhnEh{BiSG‰]?`UNP6^Y3Xh4gmAtw@rŠNt“Vq“]w‘`pYs‘d‘^Š™`‡¯‚ƒ¹‹³vb nq‚_dŽTftRbrFjNs€Fƒ†Db‰LbyNLvJdrJ™xD‘¦Ss“fdŠUf|Kd‡Uq}Nzm9yuMg‰Z¢Lt£H\œzwsOi—@Q]M|Ijp%‚v3VcO{cKs4Mj&G\'Ne*`k2WnCR:ŸŠ3¡Ápʺe±Ö…¡È“¢qc§pa|Xtu1\Z€zZVš@YhD}r;’K­_|Ÿy‚e¡šj³½`|Õwˆ lx«[{ši…£[†±eÄ™a—æz~¼œZotiEŽw:qW©a¤®l£Ê€²»¬ÙŠ„Ò¸u¡ŒhŠ]`‰Jy~D†˜D‰µn‰³]^­raw^hu6Š}å“OŠ¿~¶¨W…ã}šOŒ¼`²¨Q™Ï„ÓÀj»ÆŽÿψÝÿŰ쉢Áˆ°¹mÏÞœs±§E^FH\)‹}1ŸÃ{ªÆ§Ê—¶•h¶é¨[¸CY0‚](ÿ‰dšÿÿާV«ö|¥ÀL·™~…ÏœˆÏe¨±L‰µj~T¬©Œ ÆžØz“ÆrtŽa¦ƒ^¡Ü¬×s…¼€‚q‹¦P®¦hæå”ÿÿÓÕÿËÒ헄Ѐyƒ8|€=x¸tf-xžUŠˆQ‡¨[pˆHxfI{f½ÓYÑôŸÓÕ|£ê‡ž´H–âdLÕž™ Ð«g†Dw’O„¤_¤”x²Ëp¸Ó‰¡Ä‡m„ž’eœÆXiŸ=›xg™z¶´¯[†DDU"`7ºÂ‰[f;Š0¨·WÑþžØÿ»zÎm•zFº¾q“’M——T…†>–ŽK¦™vïúÚÿÿÿÿÿØÑÓ¤íµ—|›QˆÀ_¹½Š™†Fìè—ÿþ¾Á·ÿÿ·Ãÿ§z±P¹Ô}ÏöàΪÁ—ŠÛãš’§K‚UËÿˆ“ÿY¦ºx»î•¸vŸ“y¬¡z•\{—=n€DrUt†ejqAr£C…¡Yz¡ar¨Zp|\¤{ÓÕ¬âÿ™É_Œ±UаeyŽar•i—šŒ˜®i²Îu¨Õuvº\\jR_nNIh7mlQž_}ŸgLu"F^0=W+?Q!9PPh>gˆR€™atœh^t]Fl?Zu.Z‹8pƒO…ªHBe.dÔÿ ßÿ§°Ó«¼¤œ³¥¨ºv–;Zw=Ia2kŠR}mKmxOަv¾ÄÌ²èæØãô¹䅊¾]o¡CW‚_oAa~B[n[€ž‘±„•´oœ^s›liSi~rŠŸc’¬\„£g^Œn…¡ºw}¨aZsYj‚pÌxt›NjwIƒMŠ`žg©d}Ÿj‡¶tƒ«f†¢ŒÕÀv‘®ew¢n‚œw‡˜h]|HZmNexP^xFbCu“Y™p¦½k˜ÊmŠ·kÈš¸Ý¶ÎÑ‘¦bsˆQu‡ST{W[v^d{ZjˆNn“`ža¡Uk:Io;Z„lˆ²¶ãÀÍé‘¡Á_xA^nALlW_vnƒ—…¬dn:BdCdUdˆ7Fi:NqIm‹]q—Ts—w¦g|ŠXoGb„C^ˆ=W…E^[qg|•[g€XeKh{GcrC\[=ej?rs=rc4g]1ig:`„=apD†|DÍFV±[U€T{=Yl=Ws=ay=f‰=RSNuDNX;V^.Tf2Ve9rm5iCaŒR`|ZqzPoŽMcˆbcƒ`~€Q“šd‹½†k­‡p…c|ˆ\a¢afdeyEXƒCf~EqHawBsvRa†=g‚Iv|BŠIy\r‚RuˆG^~OdtDme2uu9{ƒJz‰Ux“U`’jsuW^ƒBSuQNh5Z`+\r+:~D4e@AM-fZou sŒD`ŸQrHl; ªK¥¿xµÉ{–׆n¤yy_y’Qt†L‚„Q…’?j‰LU@Wq<g2y”OvˆRd‰X–€L˜¥\¶®b{ˇx•…kŽ^u†^ƒ›X€«]ƒ`~£V|¦sfŽdˆ€Q’§Rµµg‘×~“¡xš½v´ˆ³sª¹†‚Énz£uo¡dj•V¯‰AžÅzŒÂmp§s^–On‚5\q:}m=‰ŠRœUp¥¾ RÆîˆ‹×ˆS“{—xJزW‚ù­w´¶]šÉ£y·“n‘vi‰TSqBy\3œ‘A§Â“vƃwšt›X”iyšT‚§Y¤]‰»W›{ªk]ˆQŒšTRªiHr8Gb%MV#cf6e‚@FŒ´u‰¿ƒ“±~޹h¡Å–»‘£Ã‚²‚}­cаMoÅw€‰TlœW‹‹dœ¿f¡·…µ]x²If§M¥‰LÐÏ›‚ÿ©‡ÌZr´jªG’¿j˜Öx…Ô}z’l‰^™µx‰ŒJ…L?µ˜S°Ðf±¨[œ¸sd‰@g~6•°G‚¢Tˆ¡cj¦kx]>zQ”™Oõ\wÙ³€€E¬TœžKu¸rŽ•H—~m˜›\ža—§{¦£iy bƒJ¢¾j¸ ]ˆk_x9Um-My1vcAK—dUb#Ž‘2¨‘ŽMœ‡nl.–¬ZÿÄl¢ÿάSûøž^ã”Nf!v…I¾»eÿÿˆÿÿαÿ”Ƶ}¸Ë¸ì‘àwj™F‹h+•šcuŒI}‹cº²c»Æ–±¶{Ä£“ÿý»Ûÿ¼¡Ñ‰†«ižšYŠƒe“¦h‚¢Gp†Ino5`‡E›”Am—Qy`7oj>´Áƒ¹ò‹—¹pl›He‚^‘M’µtiœ[Y}*r›@™ZzœG™X‘wLŸ¤gˆ‰B•Šb˜ÇpnŒ?iŒJ6V#e9BonKnV+±ˆW«r†ÃCzV~]–¯u¾­€µáqšÏQ•­S‘»gØ´søÿ®’Ñ_׺}æùͺֺÿÿ⋳Z\’0n?{›`™¸fµÕˆ·ÇŠÈÒ°±ÝªåÿßÍúϩϟp“I¯ÎjÖÿ”ƒøMv†EÃǼÞá·ÿÿÿõÿíÿÿ×…éar˜KkŒ=Xo9FJ+eh,hlB[rCuvAy–G¥ª^§½hÛÿ¤ÿÿÃÐÿ~–¼L€ŠVwgiiHv‚I”bŒ€d^q7rqCp‚Prb™±…ØÿŽxé;Uƒ6.E3NHXb`FheNT};:d"8[!6Z=Q"K]1I\4Wv:d‹>Mf8]nX‚‹luš]s¡J¹_ŠÆ\¦Î€©Ó‡ƒ°‰qœ[Z|3`ˆ;[1c’@n–EhDª_‚”Bo`Àx¨éa~™R€Šq±Ÿƒ±ÐÒ|”ÄQkˆA_wAPwA[†KkŠFd…UeEMjA^vqhpn“`mRsŒd‡³i‘£Rt’S~¦Wo¡]…§ahŽ[gƒY²]g†\Œ«q…³cf‹APqHkƒV‚­p‹Ì—Çulƒ[i~]xZvšr”¹~¨Ì™Ío}º\azRixY’ŸZ~ŽQy‡Mgy@pŠYz–‚©Ö Àøƒ£¾|•Á™±Íˆ‹¬–¸Õ•™ºfr›`|šNcz9QoHd€XtŽWkSeŠGb…I_†I^‰d„žz‰ŸŽ›¾lr¡gv—QftH^}S¢_£s£¿jŠ¥M|‡U}–n”·n~®fs”\Zofl€_^…\]zSZ}]n[r‘?X…>[†ELg3Ce.@b7BiO[‚KYxNiƒJh~Eg~@ca5`_:Qd4_e.jo8h}>ru?®ztt?o}Va†Gl^wƒ@y‘QyKttE|{DotU_jLZr>_}6vxGdFPuURjFFuFAlI2]COG)Pt4uµ^E¢e;n>V[(ai#t„H~”\Œže…XŒQ—¡[›´t¹„…œtj‹Tf„Oƒz:fŒYŒ|CyšRg¡VM„M‰g9Xš;]d]r?uo?„GªÎpl͆[ƒzep<†wCyªXŠžY’¬a¬·i±Æu{Ï…k¤€rC§ž[w¼{p|lZR\vM{qMžXޱh©lp–fgšP–}H™¦X¤ŸlyžW|’Tœ¬G‚·h‚Šch•Q]oJ™Š@¶Ã[­Ä„ш£r¦¥Z²À¶™‡ €D«tfPI{ŠPŒ¥I«°_’„oŒ®D‰šJy€Q£›m›²mg›kŒŽO…¢fj†YŽ–Lx›J‹“p‰±zmª{eŒW\\Y‹?Wˆ:W|,_Y@z‹Cš˜_wÈxx§]}Œ^¢¸S¿ÜŽwÑnbŒyj•»ƒÄxi¢ok‘Mm=_ŸV‚‡G±´{º¦™àzm¬rs—L~§R® w›Ú¹¸•žÊs€©ˆtž`s˜gbNІAå \‘ìšs®^`yY¹i=ÙÑŸº‚–¥\s°`^1g‰>YyD˜€4Œžgƒ†W²]—Òx ©V„©†ŽBµ¸N{ú‚™¤8c¶E€U7›May_–tQÞ XlÆtcz<~ŽS’cÕÒ}b¥l˜C«»cˆÂj“¹aŒÀn”‘q‰¹eNŒY³Œ<Ðø¤ÑÎ{•’©ÅvåÛƒmÏ…ku0V¤T}Š;¹‘Q×֚昭´Uv ?À‡_‰ÐŸÇ¶\¸ø¬l[šœu”ÉL|¥X}§L}§^|tPKÿó̓æyÖGyš:q‰D’TmŽIiz3v~;]k8Yn*xu2À¸j­ÿ‚Ìèxw¯s~˜‘²kXT]o0]r(rv<•[‰¹tw“K ¹qrÉG‚’N¦gŸ•[w–Vƒ†YÛæ˜Ñÿ¸Ìÿa£<~–HeƒF†oZŒi]„ŒT˜±el¢`„dLsXƒo›¬Ž~³J‡y;’g¡Àp­ÉwµåŽªâiÿîÓÍÿ²Èxc‡M˜€IÅ«‡›]€xPa”¬‹ À–Z–Pgl@¥©zÿÿìÜÿÞºÿ´ŒÇk»Î|¶lîÿÍÔÿÎûÿè×~´Å…˜®i|•L“°Y­[x‰V|¡[XeD‰XÆÛ€êÿ¿©Ï¬Óᄐ╙°oŠ–f”‚L‚‡=—˜T¢­^Xk>¾É~dš?¢X|©P¨¡‚½ž¤ÛöÄÛäž‘èT>k&7e+9W(kž\… dŒ¨SñÝeÿèed«,7T To-Rz4cƒDbŠQ_{@pzh…¢w‡¢yz•tjŒM|–q§Þ‘¢Þi•ìPež>q™OeŽGW~9]€EsŽa§e’·o«æ€¦Ü¥×g£e¯a¢Ãz¥Æq›ÅeoŸCV:f”Gr›W~¡^fŠIQb7gsJ_’OX‡LYrYw‹c±‡œ´qŠZˆÀv}Á]f•[j„I]O{®zžÄu}hZjSuŒVd’M^Iiˆl’¹•»Úš¬Ó„ˆ¹TaˆEf|Mwl™³„™Þ„›Ó„—¸nrŠW|”g†¤hoPq‰LftDbRoŽa¬ÏÈÿÿ¿Îó}†·x´{w£x—´¦¤Â ½}ƒ Yh|JuSy`tžRl”JqDVsIc…Hf}QrˆUa„co`{ž``xCFXIj‡n’°} µu’¬a„‘Tz…Fm‰i…£uƒ bg„GQuESuGOhPTxSXpOPwOk…I\~Jb†Uq…CWp1?b7NtSq£Xk[c‰Zkž_~›Hhr?f|KR€QRk=Rc7Tn6Pd7gl8Ek7G_Q[`8qe0pƒ9Z†H`{Ph|Jj†EWxUOwP[e8^]4bf0ckATtQLjDZ_1il4oAo‹FRŒjRhWM_Ih`H†pAsŒWqˆin†UmQeŠZnwOˆuB„ŽRw•Xo„[x}Sz‚Gs“W|ˆ\€G}‡Mo{KpzJbN]vNoD€?r–[‚†Ka¢OC…l+]E@=YN£a"“­Z}·€Z¨sWwMnj3iƒCz„S€¥\tazrG‰qDŸžlŠ«jrŽiyˆXr–X‚’?gžh¬uR•µQz³uv¡qx“H‹ŠSt ef†Ra{>ž|C˜ÇOW¼ckg\ƒB†LˆÔT|±mr˜er‘j}‘w„¡evžu•œc…ÂiP¬tOsIP~8=xFQ](ro1‡C|°`‚€VkœLe‰Jlq7¡ˆ<¦¸a¥Ú^™½oo­ˆxyMsr?´j>ÈM¡Ë—Ä|~°–v‹bguiyŠNoŸ\x¡]l¢gc—?{™Jz—Q’r]ožU¥…r©žl¯¹w€Ÿ}p’kZ˜HtuptKœT§¯x»¹ˆ“ÓfKœhB`@6P/SW$^ƒ,r‘6e“IzJaŠj†?¨Äb}®~ˆ¨kk¹xo™Ql‚T‚žbo¤g{`†ˆ>©¡d~¼xy©c}ƒ`­›N½çyˇÇa‘®e‰Ëq²ÈrpÄŒy¡br“cqR ¦M‚Éw…ºkw¥h†šT­iÅÓ`ÀË‚Òæ¢°Ý”­º…M‘rAi/Na"ux+\’Hwn3‰l<•™O¡mz’Gm<¦–I¯â¥‹¥p{˜Vrl;}|9q®U¿•Dƒ®{·¤u»£b†»z«‘W‘«Že¨WŒ„Hª l¸ÄZš›«k¿±ƒÉ½Á”ÁƒÛņ¥»¦ÿÈ¢ŽÈŒ®Ôj—Ÿ„u¬h§—Z^š^ssE ~MÌÓÄŽ\~Hf…*m….‡µO^‚WmrN]}@½Åg“Ãs¥g†¦di{B¡I•ºeÄ’]¡ò±ÍÊ”o¿ƒj‚9Œ’WpµSŠˆ?^~Bmx½²ÿÿùëÿ¦Âí–çý±éÿ·”ëZ9O)lL=shI~eGDE-QL1§„[|ŸL˜Ði™×^«½}áýºÿÿÜ×ÿ̟挣Á•m£_P]M—~ºäš¼œÉÙ¹¨Ïa§¯m§Är–Äa‘ t…¦]Un(uNn‘XS_>‚œj¯À‹©Ý‡±£¤²Ýg´bèj¢¸q˜§z¡\´¡Œ‡·T…©dn„e1@>G)^\L“Š|—ªk„ºwµò„¹ø€ÖÿªÆÿ‘³ÓŒÆ®€ÞÇke—Xag3bp8[z;pRŸQBi'\p3dp9R[-0B ?P2gŽv›¸¦¡·©Ù˜ºñ†£Úcf˜7]Hb”P‡ fа€¾ÜžµÙyžZZ|WcwYš{´éms²QtŽLlL|—MošE\xK\wF\~M„µTs¬eйrz¤Zh¦Qn©Y–΃¢ÞnÃf›Åj„«MkƒYs•X`}e€v¡UYu:U[5V†Fc˜GgŠMj^t£|§Õ”µØŠªÀeuDfIbƒLdƒkyžqžÍƒŸÚi„§f€¢[u†e˜“m“¤Xn‡Nz¥]…¦_„¸ºÿÿÿÿÿ®Ìæp©|€™dmrŒ–z‚œsq]w˜h™»›Å¡¹dx{@Un4So@`‰V„¤ZŸ]r†UoYiNZ}/.L3HgOf†fm•o«Xq—=X‚=TƒQeWe‘c«m€¨Zw’MltCU€LX†AJoNb‰MYyReŠfy’Tj{J^ŒYj˜apžV\~HWvSj‘imŠ\h„W|‰a`ˆiY}MflEg‚@a‰KRzKE{DPY9L_.t^.ju-Z~Qb{Si{?awG[xMatDpjsksu7¢]‡½jWŒm^W@{f2lKNŽfbO™@œ­c†±Rot¥‰Mµ¹L‹Ï‰e¢yS€V~kTƒ™C|•cq„E•ŽT“©IjµwvN†’J¨žc–ÁcбxnŸZsO~šTd€”i‡Ÿhb›]j_k€:qŠFƒ•YZu9{\3J€®Vz…UTw@WsDiw2‹y/º©F€£}†ªi¨–^ª®s¼¬QŒ­`lkŸ“T“Ñk´vwSYx:Äq5†é\žk‰±m•»v—Òq¦·‚©¬rƒÀiRy}ŸsJen\ue[x…O‚ŠRP©J‚o6{¡ak­ZiŽHg~Zl{O|’Qh¡[@}V5K';IpU!~¦Vt§gƒ ^hªQd‰Hi’4yŽGnxN“Dy§~YŒ`~x5WROvB†r9€¢Jn}eeLWlQyoPy‚L×µV„౜ºn²Îp­Ôv‰Ö‘¨‚y°wo—drV·¯GÎÛ›¢ÿ¦€än{œL¾Vu§Fe™<£‚;…¬t_‡JQz;W}-]„'x…2€›DŒHi¡Qz„7všRm“MŽ>ˆ§O“¬dŸ›\“£R‘Q˜¢T€ªs¡rO¡`Û³g˜ÿ²|‰ft‹:…wP‹¢o—L¥žoˆs£v^À»m¥q‹K‰qHTƒZp4ñè”¨Ü…Ž½d›·wxÉh“·QdOM_KYR,w‰Ot¥D‚Mv®f¤T‰ b—_n—CXo%Œ‚-qÁd„qH‚¨B ²nžÆs’Âlœ­YèÙ˜mãuk‡Bc—C`|3ŠˆA V“¹R–»K§Uv§P[ubl@Tl0ap9]{?@X(SU‡n*®„F‹¤be˜GxqF~m;¥ˆZ‡­h—¿|·ª»êʰڌöÿ±Àÿ²vÄbT€>ž˜fˆÃs^‡BEd,ˆ{G¡¸bÆÂŒÞöʨÊr«®Jãÿ”Ÿ¯t¡±p•­\ÂæÙ÷®ïÿ¾úÿÑcÍ\bG,¬ŒR ©O¬¦o¨QWu0pT[ͬº‘çt†›J¤ÑˆÇس·Þ¹j|€p{\—²‡wM¤ ”ר‘ŸŸ\¬¯ÁêÎÈëÜŸÔ‘­Þ¸¤áŒËwV{5lnBGb.9E!^jCˆŽwª\SŽ5€™Y—¬_‘¬x•’_‘†o‹¤jLr5j]=£Šx¯ÖOIb"c|-b¸3Z‘1†¡]{‹h@HM5=3::\lXs«Ér²ïy¤ÓvöÿÕ´þir}UoyLŠ’_Ëï}¤±m¨¾¶Sp§J_³:\}Z˜¼Ÿ|©r£„Âßµ§½’¼ml˜P«jŸãŠ·ù|´ý‰¬ÿn£[Qm:msR…–VwW”‘~‰fuzSa–54X4V†Ln±Tn•W†§„•Í|‰ºyv’kpše€¬ ÏŠ«Û‚Êw¡Ùwy©Tr–K·f†ÀehHUzASnIhH¨i¦ä~·K]„OmœfŒ°y§x¥¹‚uLm„S„¯nº_w]o›e±ƒ ÖŠ¤Æ€’¤byScrc‹œx‹®†›Àv€©^}œq€©—’¬Š¢qˆ•dv…PkvB\sY|“l„œko‘u“¯£·y‰Laq=Yx=X{H^…h{˜b—t¤¨` v±³`…©Nƒ†AsBdƒHf“m…ŸZtƒ4U|Z‡Mof?{i>qoLbtODy]C]FfR2fb0‚wGh¢R\yk^sGcqJlxFU†OVqMah9ifZJj~3e‚Dg‰UUxJLq9rj.WˆN{i;N“QFb=±[.šÆ{¨Ñk«»ož›€²¼|¶ÚzÐׇ‘ç‚s…yt—SŽmƒ¤c¾XŽºU˜¬[j«}–O‡¶nˆŒwx¯br™S’µQ–¶g‰ÓwhŸTX@^W.¢ž?ˆÓq{J¶ŸP®¦z‹—m…ŸXsIeBƒŽCiŒKc‰=\m8€‚GpJ‡•Lf•U…ƒJ¶¶‹sg‘‰EŸiBz¢bmsDt‹M ›E­ž[”{s£d¡:›Ë]¡¹Iÿ¨a©ÿò aŸº›è½Ž­àËrˆ›U–ÓXƒÉT™V Ävš·Z¤ˆÃrV…JI[,Mf>HS)TZ+’˜ek‘O¤Êj~¦WŽ^œ©x‘—W˜Á{o§}„—,›¾sd«U|:–”g²¿ƒ}“h\ERu=Sw'Kx"kj3ÁKø­…½Ã}‹”E“¼[kªCe†2’y>˜®^{‚Fif7€uSy°Y†ŽT€¥J•žfˆ¢z¢w¬‹¡ÂÕí ÀÿÅàÃÓ§ÍŸ‚¬q ¸|–°t•¸{u¢s½˜hœ°~€¨|Fi@fe3Z[-iŒBo~6t…0³­rØÿ¤ÖÿµÒú³Ú÷Á¤á‰ž®aÍ©vͯ}†X—¯_¾ÍÚUgº;dCއohžqKK7a>Ff1[c5ad7k|Ejx8LW-V^H‡ƒ´ÉʳÙ˜ϣ­Ç¢·Ë¦o–Se©:Pi+AO*`…4H¢&}‘YÀö²¡Ý¬À}ÞåÁßÿ§¼ÿ†»äu¡Ïy¯êzÇÆáÛ«¾¿’Æ¿wÿÿîáÿ¶áþß¼ŒOK64C6FG‚,O2i’J•´wÉàªìÿåÐÿ³ª¾c˜µMŽ©h®ÕŸž×…šÐt˜Ô|½x„Àrv¢r‹¾‚x¹ek”rž}›¯mžÇ‡Ÿ³–œ¶‡´ÌŸÏÿ¡Äÿ–¥½}¼JHy,?q>6c=MJ&FN!aP*Eh/I[>@\2GT1fM2\d+_^@aeDWbFae>\h6ac7Z‹Jgo@\o=N_BYR7Eb6ElDfS2k^%ƒq?~•Cf‡cvvTg…NzyQu„I|Y‚ŒFsŠFnP’I{£ngq\TnAck@€m0qˆOl€V`|T\nUŒsI‹­RŒ°m¨vu™g‚jL›…5¦¶p…Í’X³ŸkoMd…Ca[Z€Fjg?h{?|‹cp‘_{‡c…y@“…W‰™^kŒdjŠDs‚L†šU–”ZrŸXgŒXi…HlQR‹_InFsQ1py5oKjGp„Fj’@WrGia>‰‰?q¨]X“^sv:cŠ=]}Mhd-Š|5„§WŠŽbˆ–V‹OŒ¬…X¤_EW[‡b3žE„·Oœ K‘»ao»hcŽmxš7Ÿ“J™Î€„Ƭz¥€P<‹€zmwjA”@a¬ql=^‡FN€+OnBbp-au7Šz:ZMgwB{fVz%v{L³œYyàfeˆ%ˆ‹O§¬V«ÕR¨¨pjuBZ‹4[{r¨5Xp0€ŠRgeIŒ€@¶¯sš’PÈ×›¯oe¡Gxœ]l•;kŠHEv¡>sš\z†A–³{m—VQ^;€Q  oƒŒe¬Î‚ÂÇ’—µe|žj«Ã†Óíµ‡Î„ÅÒ‡–ù‡cb?ƒ†R’¤jÿÿ­®ÿ­HZ!Š{7Ÿ¦L¼íu¾É¢—€Ç’Ó’†Ä• ¼~¤~OõÓž–·F¨Sq€LgeP©h…€u´š‰¦Òlf“QGW*_w4i–9\\<\…8/6A>-Z\*Pb3glF–Œ‡Ñð¯ÐúÀ‘º‹ˆ¬^t‡HnˆG‹…Kg¥?dLK ·’¼|˜Ê‚ˆ¥cp”C°¡ŠéÿÃéÿÏÂÿ¤íäœÊß—µç}²µm“M›o𦅾»¡Ÿ¤Š¼É|¦ÍQw¶:i‰;ª¼ˆ¤át`ƒ:‚‹r¨Ùm¦ÜŽ¦Û†»Þ„Áÿ—ªÄ|Œ½p²†©ä«ë†žà|q¹ahŽn¤ÅŸÇïž„²XU€fl8h}PcZUxPRe=Bm58^6?T.IL"]T+Hg.MW=Sb2_^3\V1IV9dJ:fm6nrLo~N_uFge=hw8pd<_e>DlBNQ4]b/]o6aq?[d6qc=v‘n„\_›LVr5Ye4qp;¤œ?n¯}^˜N\y=]†4kƒ8OyEGj<]f0fs9sq4~…ClSˆqXêe`•}yh?_’_Tj;lubpH^]A¢{9ŠÀy„Z~¦Nu†K®ŽIuÀuŽzI¡±MjˆF“ƒ@¿Æˆíá¤ÿÿÈìÿé€ù[‡:k{'u•N¥‘S‡®p“¡[¦ÐtaŸn™aoõÇg»Š\ŽLR|.VR@oFC§zŽ›eµ´a‚ËŠ‹O¦Ì`ƒÆ™†¬Y°¿ms¬kxªZjƒN˜†L¤É~›Ïr}»r‰ˆK‡´j˜µj_–bH`&_g.hq9^Œ9¾¡F·ï’HRf@OGKWa:Ut;X[+HmGfIc5jŠ(¥¼\µÖˆˆ–a€š[j{.–¬IeEtd>±‘`¼¸p—Ål¾‹[¢Z÷Ö¬±Ó„‘±…–Ow»H{{8€¸pNx7h{.d@cs?Qw>ER(`kJ™¦pœÔŸ¼pdŸ[EL+QY,oz=ÀÀ‘’ê”±³fìÿÀްk›°pæü¥ëÿì³—‹£N|¹E{@’›a‰TŠxQÔ’g‘ŸM¥‘bËÊñÔ–´¢iÌé›™Àuy¿HÍÝy¤æbËß~¨ÁiÊ푞ª‚Àç×ÿÊÉò¬Œ¾R^v3k•3¯ÿloÌ?ˆ‰MƒR„šn~pަywŠd‰v{x¡VXo0\x6š¡Ugš@‰Œt»à±˜Í‘wœ_t›K¬¾}Âä’Åâ­ÿÛ¸øý˜¥Ï`µ¦±Ÿ½ppC¼°kÁð‡¾Â’²Yž§r×饿ìk§´W”´~°Å…Wi(^[B™Šo޵\…®T Ü{ÊþÄËýº¼ã—”Îu{«r{”z‚•p“°l—Ös„Áz—Ð]7Go'bŒDz J]’:p¼Bl‡?i•]…³^vªbu­j¯„•À•š±iuv6t‹7n†OŒ›TK€fTY8W`1KW2Mk*cl=`u@ƒ:°¦Y”“W‡K“˜Mt‡VX}?lƒ.dˆGz~LežVFo9Zh+Ê4’ýž‡Àv}„_~¦W‘³_¯µ|ÿã¦ÿÿðÐÿÛíó™wÜ g’Wf|HÏ”Q|Í…²©Z”·‰m·pk“Gs‰Jx_HvC^c)ThTVJ6‹ƒ={‚d{¥X½¦j¥¼}ަƒ‰¶ˆ›¡t†£‡Š}\ocfpCœ›FãóœÂÿ¢‰é{r¨_wŽG¬J`€;_v'z­C‚œP‡¨qžo’¢oLxLBB$;P3IB@M OR"rŠ3N};”ƒUzšWa~4veg|p¦xe†E‹rFž~TW5qm=Š‘C¦­v‡Ásk”Jw€O¸­u‘™k…Pp…Oq‡NimBŒŽy™zk›:Bk“3‹©cªL‚¾ju¡f®³‹†»©~ƒVf›KŽ]g›Uaz3¦®”~W À~“dw‘_¹³‚Çÿ¬—æcs W`rKzr7£E†„`YL8}bGÊ~r‚}Zˇm­l¹™cÿÿÐÏÿÄ¥]”u·À‘Ѹ’tÆW}th{„VÐάÿÿïþÿ­ýÿÈîÿ¥ýÿÙçÿÚÊÿ¬˜ÜsÅr„šgiŸRkgZH]0?T,T\8Tg3bp5Þåž‹Å`l†VÀЯ±Û~z¥[Pr8zx`„}h¬Ä}–Í_—¿_µ¶šÔÿ‰œ×^š«X¾ÇŠÊ „Ò›žÍî­Ñƒ©«ÉÕŒ–¹VŒ‹^h_7l_3so>Œa‡ŠƒlFˆx=•kLevKqtOæz@ùºW ó™zÓ›h¬skˆNxT„rHh”_N†cAgCPH-nM&¢z1~¹hr­zt•WQ‚Q_i;l}:€E”Fz¢[dkir\MˆGUu@{t8Y JUZ‚¥U™›]‚LŠoW‹†A’šXŸažŠSv¹Rm‹Rq~B^ŒD``<½w9”›Iͬk‘½a}„\~|8v|O¡>‘«T„­Sºg{Âc†ŸfžšN¢¨G‚¿pl­zg”kQŒWDc@]\)~¤>…žk ©IzÁ¢q«\w”eƒ‘TzŸf„Iˆ¯VŠœ\½€N”Äag­‘MyEdw+|k2˜¦Jj¡\n|G‚‰S[«S^‚MŠ~6r°SÖ°EÿšdŒlYLS|FXe0t|ChŒJ}Œ:„Xžšw‚«„h£nQ{Nil+n‰Kh=x˜K¹ŒSœç{i”eThDo_7\h5x~<œOT†iR]AOU2|o5ÿµO‰ÿ‡~¦Eÿ¾ToÕƒlH¿mBq¡op’>~C™Zy³JZAb€5”©J–¹ov°m^ OŒt6ÎÒØÿ•›ÿ£Çm¶Ü’u®– IÿÙoüÿÈøî«gé¬w–G–˜Q‹µneXƒ¢V”„`reO‚Mhq1\uAl+AH"9S"RJŸ˜eOŒLVc.sj4\–EUr(|Er¡c†–L›qQ{CZh1de3fLžŠOˆ•S¤\¬Î\žÆxv›=¶†N|Êka„@n–bu‹Sl‹ZVw:Œ‚G–¸m¡ƒ^|§`–©wƒµ…|¤lg‰Vmd?a¦P*Z!7'&DZ(ng2~•B ŽGÇÙÀ喦ޙs{v_5A oa4ŽhS€T;“‡Cuz@`B²[T¥„cŸ§fì˦ïÿÔÕùµ¤¹‡Ÿ†}_rG^wF~US¨kt–TuZç¿Åÿÿæÿÿÿêÿ¾æÿßËwžÓ•ÎuÉê‹ÃexNEm'WR/e†:}XNb*Zp-|‘X§¸“¶à«ÑßÌ´Ù¦‰˜^Et*RR+Ns(@F2…xJ˜@“¦?›¯w×û©²ê…‰ÚR|>•®^ÈÔ…ÊÝh¨¡_a^=¶˜cžT’„XµkÎza¤•Jph8qq<‘¶`‘½q•¡eHdCyn€¬jgšYnžZ|±h†­c’ai†Z¹ƒ³ì˜´î™®ñ›´à„‹½qt Pc†6Nm>`qMHb8SlT‡†^]wDc~=\zEuKs“QnŒTj€_lyGe…GaLod¶d…Ÿa…£tu‹N|«Ut Zm”Mg…Fj¢S•Óu›èp—Èn”¾nw­MgˆN}—d~™dj‡JJh-F^/NjDk\oƒ]€ ]f‹Tu [o­RpšIj‹W†¡e‡®a|›Xˆ½sŽËm€«q°wŒ¾^r¡Nc„V_€Tušc…¦aŒ¤o€«qŠ®adƒV‚¢l}®^|›MWz>RuRuVk“C^|Ad‚_®|²_~™GUƒVv o…±w«w–¬b{~Y†„TmŠ`s•p‚”c…ƒßЕØÅd§]n‘Ku‡Op…Uo‡Sj|LYlKR|vv©€­u¨fh‘fj£l°o‡«p²q„®bx¥Ml…E\x>Qu?QqKS‚mr¨z‡·lNF!WQ!re/f?JŠW>nJNO9ec&ftDoyAh|CZyOb‰Od„Ih|Nl@_–[iƒ`d‚Ef…Uq„LhˆVPgO[Pb[1€Vz?PdIQS3RW€Ž`žŽdÜïjŸ¨’Š¢Qu®ibd€{BŒ¤`«±dƃˆ‡\’¹^â¾oÞÿĬꞫ⤲œah‚}?íê`Þߊ»¿aƒðˆ¬EºÝ”t¹™d _k’I’qP[Œqn„6i”C‰›QÍ\—ç„„škz‡q‰•_r¢ba F€„<‹¢g–¬J¢ÇdŽ”znƒIuu7qv>™]µ“]Àä”Âî±É…Þö›ÿ~K›;^a*nm:|©[¯©>£ÿ€y¼BLn2bQ(zpSub@ED6B5‚X8~cPi=bZ8gjANi7~q:ed8¥®nŠ’]bˆVlf4blDhyGtBÍïp¥Ö…Ķ€¯Ã‰ÿ홢½e©Wƒmƒ‘lJ„0Š~EЧP‘´Q¡”e|p<—‰e—Ãn˜Î—¦·…œ_th?Öew¹ZUÂO*:CT›“Vž‚UÃÊz¨âŠ…¤cLŸ.qœ@¤ÖoŒ×mv—?_z>RK*‘eOZ^8P5(P=/jS>ŒŒXž”dš«ž¬ˆx’COP#N_$`y>Mn4x|Oc|K\sGj{S~pRÞÛµÿÿãÓÿ¬–Þr}ŸY…‰JìÆ¶Ñÿ£sEz—To˜T—¶†X™L=^-=R"D["_pM«Ásrž:q®DœÎV¥§tp2s˜9‡´F¿¯làØ†§´dK|6~…c­°§¢«…™Ûa‚¬W…€TzjT§¨ÿÿ¯ÿÿÄÿÍ ®¬^}~O~vA}U²Îw¤ÙvªË™ºÚ“Pq3XS&Yf?šÌ­æ‰ î~|ÇdrŸbk‰HJTAmŠhhfi†djŠd“°`„º^ˆ£X[‚2O[4W5El'TgHgp0Xi,WuCqX€¨iq¡Xk}Tmr?Nf6SqX}¦i„¬p³m…¨Us¡OxžQw£VXŠ0Gy4RrR† z»è‰¡âƒ¸th’Vi‹R_~Df}N…§]ƒ®BLp,Dk6\yDn‹S}—WqJQtDs’}·ã“Þt³f„°p†¨`†©vÅuŽ»au¢S^glbcƒSl‰f‹®w¢À}‰·loƒ^o€Xcr?MgUšˆ“¬bi~Dq{:c]™¸¤ÉhŽÂj{¤\kŽ[u’\ƒ¯aŒ«j¤mƒ¨heƒfzˆ`|‡Y‡§kŒÀz“ÉnŽ¥Yy„v²»›È¶h€—^ˆž^x¡Vo‹OjzRixF_McŠi}¥xy§~«mx mv«fu˜ro™pwœv„¡x‰›bbObOd’CT}I^ŽxÆ„—ÖxRzC]pE†n:aŠFN`HpQ\Z5\x1Xo>Q]?P_@m\@h„@SšWeuL|x;m›Z^“rZ~X[o?]w@bx=e„Lq€LšwB¬¯Z¥ÎÊ•–©†€¦nm¢psŒh…yTƒkCƒƒL}Xf›^_ydVdDOOHiF7mT*moMobEX]DUK=WJ&kN*vQ/V^DUM6˜R/¢a4nWkNU”tSr›g\•yZ‡G^y2u‡0^ Pm|IfO÷Qÿ©Eÿÿ¬ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿíÿÿÒýÿÿÐÿ×µê~жnš§U˜¯d~«tbsKp`\bU–Q8…«_u·S„‘Pšœ> Àiz¹l“§n²ÊgmÛ—’ž?øºTÿÿ€ÿÿ»ÿÿÿÝÿÿÈÿ¯­ï½–Ê¢s¯ŽpŠhŠ’Y†±m­lsÛalŠ\‡€=™›Jšºh}–_šŽD‚„7ŸzE¢ˆB§°uÍr€¹j£§`®¡F£Õ´Ó›ÑÃiÑ™jn‘rpBCshdYCm‰K¸…Sšß‰ŽÒ¬yÏu¦ƒh‚¡g¢k¾Ådwç’plŸ’CvÆorƒWˆŽ=©ZH~^wT2a ?†DÄÕwšÒ‚„°Y‡¶Tޏ[¨¿_´Óm|àŒs¨Yu‡Xƒ’^X‰Hop6q‡;nN~„Ju£`v›Rr˜H{•BsœLo“Eo‰du¦SŒT_”Kt’A’ˆQÇÁdÑûÀŸöÂ’«|©¢f} {ζ[‡òº“·Yƒ™\‘[Ù½YÍÿ±¨t·€š³m´ºuy»”{™_zšRˆ^˜¬Weµr›‰Ho¶ƒ¢zK¢Ù•u†}`WNOšzVeÉbº‚A®Ü~ÿág–ùÌ ¢jpÕ„•Nt›s‘ªXYÊvZu3e‹Px†;q@]žC†„B‚ÇjY°Pn”+fšDzD‚¦_l¥RŽœO’¢\mŒVƒzN˜zA¡œq‰ŠAfr8}:¡ ^Â{–eóæ—Ûû²?™vH;!hu2Á UÕý©Â쟜ò¤‚°Bi¦MST5JG'T@!¢^0‹›odpHGW*Qa-MN-XT+td5}bCrÀghpEg{>|ŒH„ˆG¢Íjo¡\uyY’“l®Ïp—“€é¸Ïè“ïÿ¢ Öf°ßp¢×zŸ°vÐè’×û±àÓ|ŽÀoÜ…|䨻Ùã¯Ã榇¹yTm=€z¦²ÆÿË]¯:²§WŽ»zƒ›RÇžo¹ÿ¤qN“±o¥É¦žÅ¬Û“¼ÿµ©ÏuSm@e\9ad.‘KB‚_B}nFaC4iM:z€Y}–gW‚79Frj;p’M„¬ZÿÿáÃÿ²?t'(F;4"ÙÊ êÿ·èÿ³—Ôtw·MnŒ>‘¹` ¶q½cg½T]TNÂÌ¡׎»ex¾RwÇa‡¶cz©K¤T¯˜“®à“²Ô‘‰½cbz1p„=›w_‚†gy„e¤¨pŽÎT¥ŽbŸ–Y“wžÊqw|Cn~Q®ƒ‘ÿÀÎÿ;ÿØÎÿбÚÎZŽ}S£·z…·s}¢dNt3c‡B…´Ws¯P”zN`Žgž›•·æ—£Ê€Œ_y¬GQBW‚EKw1EgCZ{B`ŒEjŒ?t¬Jc˜|ºxkšQc‰ESzUUz4f„+Ss9ft4`‡Mu‰<©}MŽ¥t“·d“´yÅËp滑¯ñ®~Ù†kXjƒDUm:\f3[p5‘†:Œ¶U„£_}¤U‡’T‹¡Z‚¨W…^ˆ©gŒ—`›O†­V·°PÂê‰ÁƤ£Ø×ªÖ†‘o®‚R¤Æ—¯° ˆÊs‡“fè¡TƒÔ¡žn€X’¨JžÌgˆŽdŠ›t¢£nŸ®n{£l‡¢cš¯iËÁd…â•f¤Sd‹L¦°GcÌ\r@N‚<3Z:XW"¿mI¼¹tâÕp«æÂ„â€m¯L³BÒð†¸ò¤Ãò{Ÿ¶–¢—²¯œ¯µ¥¡¿•„ ‹r—~k‘Nz§X‚…[‹„Wv—V’ŽFtœXs€Loˆ6’=…L¨‰ašy[‰zM‘G}»o—¯]¨l–­s´¦gd˜bµ•DÎñ‘¢»—z–|1MGXQ«Ÿn”¼jÚŒbÕ«lÿÿ’íiu€`jlCp…CX],„p;Vq8ˆn:‹§{y|G™ioS×®z”õ›o¼R½¤Y£ï¢r·][;gŠG„’^Ÿ½|ÿ×£‘¹h€j?Ä¸Šµí«¸jŒ£I|˜iIg+eS+›ºc°•w}MovW£áh»Øhÿÿ»¹ï¡–¶yØÙ²ŒæŒzzZ£ÀŠ]ŽBs…M‡µ{­­œÁö·³Ø•ž­p?i4SO,~mGžƒK͹x Ùio¯FˆxEŒ‚iÅ^l¤BµÑn³Öt“ÃdïÿÒçÿÕÇÿÜ3R#29E#2?.44/~S\µÈv—Üa¨ÅpÆþ¥‘Æo¾ÎŸÓñ°Äõ‡´Ö•ËßȶݹÊá¼Ñü½oœ[OP>¨Àuºû”üÿ×ÿÿÒØÿ®¨êm„²X^}Ašªl™ák¯²‚”{I}rGvy<µ¹j£åm²^Ä•{œ‚oÌ®t®¼fÊ¢¸Ôw¹Öo…­N’›c˜©a¸d¤Ø„¸ï•·üš¦á~ÁV}–eo^ao]žTGm=x•_…Ãx†±h–®i‹Ð_W’AC`%Gg(nxGi@kU§Õ©íˆ§çu~ÀP\z8nzTaxWx†Y`Fg†[‹Ÿc| X[t?_}2a{MS1Lb*`\-~k0}’E~’hy†YrWyS}…b|zd}~Vl}QovZ~uWvvLqcXd]JhkStx\mƒaysWÅsC´ªPu®s_{Tn];P\/^B.`P)U_5dP6vu4~‘W«†mϸ`²ýbÛ¦O`gwO1«.¬Ñar× … ” ˜QÿšpÿÇvœËµ­§§ÿ¤pÿÿ ÿÿÿÿÿÿÿÿÿÿÿ×ÿÿÿÿÿÿÿÿÿÿÿÿçÿíŸâŸ™Ûy˜ªeœ£gš¤gª£h—±[°™p“Ì^±¶TÿÌWÿÿ”ÿÿÝÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿùÿÿ½ßÛ™­™¨¨[µ•H‹cDe9SZ+q/{œ6Ÿ–UÖ³]ªî´wƇpœq®OÇÈn­´u «ly¹i”rX‚ªco©k|[˜J‡·aœŽ[›œtx´‚±§R¤ØŒסc®}QŽSO^=›j Ô»j¨òÙbŸXXt}q0|ªRYªWndI}šDmPnˆLm‰Wo”I_}B^i9OcJmp8k•?L‹@@j8w] ©ŠGÇ©džõmaš†AuOg\9Š~H†œop¯Q`ŒEkp6n‚3v§DqŸVx—V`ŸTw‰JœLƒ¥f—‘Zy°Z[„^Šv>w±VªCvË‚›‹U¦Äƒ‡²‡i‹g`ˆAslM£Â[¶¢lö³z¿òªuˆ˜—>žñg¦¼n¤Äm•iƒƒR‡VÌ›YnÞƒ‚€Pʸh³Òª“ê}Z‘eÒ¢<ÿÿ©ßÿÓd¸‰g…>‘…4¶Ã^{§kÞµM£î´~†X|¡Op‚U†©]‹§f»ÅjšË‹µb˜É_Ò¡[‚¹‹‚–]¦Qn¾sv?XvF^V/cg5^_Bs‚2t—Mi\>Wô€MÛÇ “¦f”{G«Nn‚Ks‡Em§;†‚M`­Qr„2S~8@m*(R:<‰‹(fÊZdy;›|VÑvRÿÕ’ÿÿ¾ÿÿã˜ÞœoOjvPbf)v–@€±Jd‰9Ž–Cp³c[_A^Y;ekNr…KŽV§·q¥ÒªÝvnXk™Fœ¯bžÓ}ƒ®b™™]©µo‹“fv€UlwPš\ßÿ¿ËÿÈlÔV3b ½GLæyŽVba5ÿ”šÿÌ¡ºà’u°Qe¢8º¯˜šèt Ôd‰±]£¼qÛô¡Îá¤؎Îx„Åt€›Yi=|…DŒ˜K¤šiÂЙäÞÝÌå°¢¸n§Ž{ðÿÜÉÿðÿÊâÿÕÕÿ°€ªeñîÈãÿµøÿ°ŠÿiZ“Cfš5l´=^‹@„Žqàé§¾ÿ„àÿ¹£ÿs‰^Òé´ÞÿÏÝÿËÔfÐÿ­Âÿ‰ÂzbŒ?´å„ÞÿÂÿÿóÿÿëáï¿™§¬²•Ïÿ²Úÿ±·ÿ~w¶Ilc.ZN+’JÝÙ—ÿÿ¦Þá”” ^·jÍpᤣÇn„aš¦z¥U“ž_„‘I{‘SŒœ†Êé ¯ù›»ô¦«Û…g†PZV>^hOg{Kk…Ls„NS{Ev–h‰²t~¹jw°m‹¸jƒÃ\y¥Ek‚4js>sGs—[w‘fxƒeo‡Ji‚?b|@b@EW3I_7Nb.Bi.Bb9U\=qi;a};k‰M{yRfŒRT^bpV?pŽ£DnntS¡‰Z_›vw“T¬sž¿L€Â‹‚ªcʬ{¥Ý…½Ÿ¢¬`åÒŒ|î¬c’jbsNt[:“GŠ®m}—]nƒPjdJ›¨T¤áp­ÃuµÞyjæ†Qc•šIh~VyƒG›ªf§Ãl£ä¬ÆÒÃêÉ‹¬pš¯f‡ h~˜Wp™PyŒ=LhRla/r…5S‡5yŠ:d–L¢|N¡ÌgðãyÕÝ¥Êñ ¸Ñœ¸¯‡~ŠanDd‹HPq-x…Ds²V”¢L7—L.T3ëá”uÆ•PoIV`4°tNðجÿÿÍÝÿÈ—ÍŒ±›[…­`ÍÕ|ÌÿÃøÿÈÛÿɧø{e¸vXd+w}Bv€Sg‚Nmˆ8‹¨Oq¥Mbl<Œ¥Gv­P¡¨_rsz—K~<•Ÿeƒæ]Nk9Ma)ž‘S½é¯ÐðÈ„¼~jŸWUv3¨¬uzžoIj@h]5Š7¦¦iy©OuŠM¤âcÈé³Åÿ”۞·y›âŽ¢æƒ©æŽžã€›æ}žÅ_¡Ï†›»n›©pt›Tw·_œz¹è½”¹†¢ վܶ­®õåÑÍÿÞµ·ƒ|Ñe‘‹i«Æÿÿóÿÿñœ×sÓg»äšn±XMs6^UEέ¦ÿÿ×Îî ²\ÄܬÅÿ¦±Å ÿÿÕÿÿÿßÿº‚¹c’¡tüÿå÷ÿÚëÿȉ–_8H 2.#šxˆ»À¬§žšÆÎµÍóÂÑÎsY7uh<­§„ÒÛ}}¶K_‹9š—fÎÓ€Á›j§©p¶ÏsšÄ[cs:„¯p£×”Èks‡X‰³ŸÑˆ˜Õ‚|•n€ÃXv´aÀs¥â©å„¨ãsÄ[bœ?RŽL‚‘—½‡•Ë…‚®kˆµ_y®=e‰5dkAxCqCv`k=Zn@ta:sW8fu?nmMx}DkH’u>…TexNge>\s=ZwD`y;Vk8l`3ƒn9 †Ec¸f]‹hHKUA7_M*gW.{h7oŒJ^rcˆHPÃ_1ÊÈj‘ô²¬°ŽÅ_tÉmYš\\j[rZ?yFu“\eŒi‡{=™—HÏfÿÔuÿê§ÿëÄÿí±ÿÿ´ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿßÚÒÿÆÏá²ÿïŽÿÿ·ÿÿîÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÛåÙ±²ÿ™”ÿ¶}ÿÑ€ÿÊ“ÿÀ¤ÿÓ¡eý·hrehtJ{‚OO§UMvPŠt;£«X—³€‰ÌˆeÅ„wm|šC¿ªex⾉¤€ºmb˜do^=hBc‚8VlJŠpCœªI‚¬ru…T˜™G”Å|aÄŠq‡a–¬>ƒÔnµ®p¤®Wª»n®ÚÄ}Èo…²j}ºa‘ŽZ£µ·ÑuÉȿ٦–í½]œ›fdLZh3sb0hu1{}LacC‚n5¸¦Q½ÿp{«©Â¨NŸ½y—¯]ŠŸPžÁoqÁ…Æ®U»À€°¬o°¼lyÚzqI£FR¶®N‘¼~g¥}q‰YV CKd?kl#u‘<\ PxdJ«¸U†Ðwj”{t§TZ§E†“@ˆs­z˜ÿ“œeŒ‡O•«uq³|†X]‡kYt;k_-\‹Mn€.Å£E–ʼn§ÊiÂϺÿÀ‰º|¯¦a´ç’v–€„†W˜„]vÜ…g:òÉrŽÙ FoBuq-~Ëhtz=”‚M„Ãa—·c›¡|œ³uÀ¹|‡³W’²lš¡Vy¹V\J“o7UwTSV1Xc-z>ˆŽd©­]ÏÐêü®ÿÿÓóÿÕÜÿÍ’èŠRu94S ^\%Ye3_u2g€>a‹DZƒ-Y}+}¬4”©Qæä£ÕÿÉÆÿeàh§=¡É\ÃçšÞúµ¬ß€’ÀƒŒ­‡¸¨xÙðÄýÿ÷üÿô“Ï®R€G{qEŒTck=w{S}vF‰©Jh©T`v6“Lp™Vcu?bn7ds6vŒ8®•_¼æ¤µú|œJsŽ7±Ä|¥Áˆ–¨’¾Š†¬o’ |tªaušEx‡9gBVt1wl=²V|€[½º­ÂîÉ£â—Ñ}‘­n–Îw•ºt’ºg–¦^‘™T§´cš¾nm–EzP•ßuŽ˜r¼ä®Êyz’iLi/XG-‰…WÎæ¡j¬2_-`y;}‹[ʰ–—Ól–ÉeÿÿÅ¡ÿƒLU0KY+Wa0o‹B³ÐuÌÓ”Õô°Ïë¶Ðÿ¼¹ð¢ÿÿúÿÿÿÕÿ Ú_Üæ°ÿÿùÿÿä{¢e:F"2E25;A'S^5`p7Un<Ž«w²hŸÛ[”ÈM³µiÌÝ…´…†szD‡O”œh’˜X³«‚Á䊰¾s–Ñ]¡Ñ’¸Ú¡®á’Õ–œÒ…Åv‘¿s˜Ñ¯äŸ¬ÛŒžÐ’±ç™¶ô˜¤Ølƒœe ºvŽÉbTŠ>NuL‰›Ž ¿š¿e޼q—Êh}mAnm2lrG«–bœ„K}hSŸ‘sŠŸl™¿`”Àf§±j«ÄiŠÅ`©cˆ»_ršaŽŸmN\w=]iAnmN€_¢¥h…ŒGVr0?e+Ml2Sl8_k9Ja#@a,Zy8Nw7Lu.5N*Ji<[IQt;]xOt‹Wu¡Rm7Y‡/TuZyEdŒCbuQŒƒz¶¦SfqDgri½¬rŠ˜Vnˆ\cw–^zœb|£k®m‚›[vuSc`JltbYwwMbA\o0?X1=`PsœdŒ£WqMWmCSpF^wBUyTvŽ`lŠLVqSd_=Vi3rb@Nh3MgNdQ:Fd+C\?BU5LW2Ub:Om=8k>BR>:M$8E.\E)AV"EW@O]&Y]+wa8€^6ushrOsuA”w>‘Cˆ‡W\‹VfjWgzIamC_zKOwCMl?|]2¡w,[°UUwiEnDMW=QS*U^6nq5px?pr_ƒ`F W:€K›Ó„µ¶‘Ëoq¿˜K…UaQ8cc*mqDg†Nc‡]zx;€EÂpEÿ»]ÿÏ‹ÿ½ ÿ¼žÿ³ˆÿÿâÿÿÿÿÿÿÿÿøÿñÞõÙéÿ´êÿó»ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿßÕÿãÌÿý¦ÿø«ÿʹÿ½œÿä©ÿÿ³ÿÿÍÿÿݲÿóqÃÕsX/©‚DÕssž†zŽ^sŠh~—Yƒ°hh¯k f޶_ͯˆç’…«ymž\f‰WGx:Sb'S`/ge1x‰½GÞñ´ÚÿÂÜý©ëÿ½¸û´ivŽ”e™³–„€\Àǘ‹Íˆž¼pfŽJXp7Õ‹oõÿÿ›»¯w‚Mv|JŠbXwvNfs9]j?el<’~Mƒ«\©”cßø¡d¤fZo5{‹Elˆ@nZF•fÈÚwÃÿ¦u­onc=©»X€ÒjIwAVZ'ƒŠ[ÀÁy¨e­Ê‹°Â‡t£LOm%zWˆ–E¹Ç[™¾rªÊ˜†Ïwеk‰ºq¯Þ„½q¡—bŒ›U‰Lz•Q‹šaµluÌZ‘’y‹—n±ÕÆŠ¢y£·|šÅh¨Ìyƒ»X‘Á\›Ël²â¤rw\‚¹X„›UšÆ\²ò{Ûÿ¿ùÿÃwöJe‰>WhD›—vÔaŠ•Mš»]£ Š¬ß—†Èmÿÿöÿÿÿ˜åq¡«oÅÝš¶Ö„SeE+,]W@ÒËX³/HI)h}7wŸB§Ámâÿ¢àÿ©Íÿ£Êÿ »ÿ‡«Ítƒ Oy¦>v8tp9qC…ŠT³o¯ÔŒ»ç’§ëŒÃ]™•qŽy³Ê•¨k¢»x™Ð}œÅƒŽ¶}”¾x ¿~£²Š©Àƒ¢jexXs†c’Ãn{ºSc–Sw£V™i˜ÈŽ£àœ†ªR{rE†T¿¸jv†=ZjGrrXv˜f™´{—´{®g†´t—Ï‹©ë¤¯÷¢¦ám¥PvŒQv•On’CqŸC_vYŒ’imzMWp@Nl.Nn+Qi2Xj/Ie(No2U‡9Iq?m€COs2Un<^z8^…?Xh=XiDj†G\x6bŽSl£bs¡e—ÂxªÒ’ŽÇˆ¶r„¸ai›Yv€V|›Wr¥Y~²FV‡7W~Ox¤d|¼m‚¯MQV1VS@ftRq›k¤½{¾Æm MdŠA\ˆ=Y€Qx„_’”y³“Llg?`Ž^xšLd|Eo~GWwRkKvkQŒç¹n—†Qx“oµ­j|…MXnRj‰f~Ÿgx¤[vžr—¯›«RprT~GUx?TkDVsO\xGx}O„~Pn†T{Š\]vNhwPphF9k:4TGKL)Wb*PwC_b;5n<9T@=>!K;ZGET"]T8^v1ak4jn9€m9w€EyxRzvMlnTb`Gin9_wEmF•o4~ˆF„{_mYJŠiLpUac@vo?l‘OT’`amHq_+Nd<8bFLV3Xm4nyAv‘Ps•Ug‘SQ”oMqc`PB©J5²ŠBŽÕ‘‚´mj¡mbyKwk=}ŒEy•R]F]xXdm6—a9ÿb8ÿ»`éËŸÿ¨‡ÿ«€ÿ~ÿà–ÿÿ×ÿÿûÿÿøÿÿóÿÿïÿÿëÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿâÿÿÏÿÿíÿÿÝÿÿÎÿÿÑÿÿÍÿÿäÿÿôÿÿÿÿÿÿÿÿÿ_ÿÿfpo­‹4YÙwP‚z^Jq~T„‹>¯lt§gg‘h‰ogƒ n‡“][¤‹^oUKrCVp4_i1Se/r*¸RwWŽªW{»dp¡X[˜e}Trºr_DhTW‘T†rJÓ¶O—ôº¹É¬²ÙœžÌ­‚º¨}ft—Uw†Vw–g—¡a’Ïvk¦ok8f‡G˜{;¡TÕžQñî¸óË…¾…¬žZ¡ªjš°ft°qsbY•nw†Q˜y€¬eã•F¼ÏŽ}µvZ•xR€Ipo8Ov~^Ÿ¦N]˜ny~8†¡Gy—T`«TcnBss:ˆŒ=zd©V^«˜¥’L¯ñŠŠ¿„k“JgKr‚PZNa\AEÝÀmßÿ•ÿÚVƒ^›f5T©Ž©g0¯«wyågHcHIB$}c/‚`’qgŸh¾¥U¯ÿ¤‡‚£³mž¶œÎ…¶½q·¿œÊᨒá^s^aS)^ƒ>xp8|@ˆ¢E…­S·¥\¡•x–Âo‘¬PidKˆF¯²]£ª`ð¦~Éí¢áÿ™ºê¥âÜœÌûȆØo{Doh9Ò†>|zLXzT:e#.K2LPU³G¿íŽÐøˆ¿ä©·Õ’°æ¡v´~c|KŒ›WB‰PGc#|r/ŒÂsŒÁik¡OZ=ax.xŠ;Ü\‰ QŠ|Kt¨F~‹G{‡Aƒ¨Sk‹?‚vBz—D£“Q²ÊueN‰I‡¤jsYV„gc–›V Èlv®an¬Epp2žµ<Èù‹vÐl^^/ƒ…W”¬VÂh˜’b½Ú˜?e2LH!›_|¸Kgw<´“Z—©Y‘M~rBs–Hƒ‚i~yGwsG¯°…¥É‡{¸g•”l—½iŸÄƒ‘¦dy£i†³u]uE•‚pŽ—}–°‘j‹V‹ r©á¿ãž…¾ez£Hm¥GUj>}oR”¸s²¾‰¢Ùyˆ±\¢¶t½ý¢Äz–¬O™á`n«;¨X¶nÒ©®µÈ‹‰­Hu£CŒ²[t²>9@D9#{[HkhC„T{ QqiHsu;Lb0pF`B”Œk³º«ÉÇŸ¨¶|¬ÁýÿÛÙÿ‘€º<}žQ±ÿ~“­y©“²×•¼ö¡«é„£Õr†©XdpKsˆRŠ®Œ¦q„žfŸ»†¸ÿŠœ×ak…Am{B†cz@€ŒP`‰P\vCtO~”]•¦u¶‘—¡•ªl€ƒQ¤œk¯¼‚’®T^t@XrR}dlœS²sš¶t¬tª¶½È龾᱿脽bl…°p…¥\e‰D[~Qp‰[lP]rHVo2Oi)Y9`E]‚=]„J€·P`9Jmb5BdCOg5LY>YsEez?YyJfTdy@MR6CY?Pk?w…T„…c†•^u h_…fU{UmeAIh:L[Ggj8d|AYS`wNI^<:UGE<,KA!_L$Bi5aaJvc.g€Er|G~zCsOs†_f‚`GnSRI@VW+Vh4re4tf-lv>€eU‡‘Nf©xXŽkZsC[g=mmCK‹V:g[?J)ND!QG)~`4•‹9‘`Žœd‚“k–•i… b^šfjqM¡j6»›J¤ÐoŠÏ•w±p…Rq’F^†[HtRN^CF_8AO/j<,ø>÷€Cÿÿ«sÿº“ÿ ˆÿßÿÿÑÿÿãÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿùýÿÿûÿÿôÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿýÿÿüÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿr½õ¤•ÎÔm½åªÐ”Çuf£t]~M[yJeyD9|FC<+vS/•E]€dqH†‡=QŒBMjOV\,u,˜˜H³µo—ë€m»žx•dC‹k„f5U­MOwIlu3r‚Vœ¡GЪt„ؤ–‘˜‡¼–˜²‰€Á¬£©lp¸_—‰U޳X«®c‡Á{J™vPt7c|&…6Ÿ†EÒ¿W³ê i¯ž®†`«šp—~y¥x””Tq¯m‚…`m­bugt}Kq}D˜¢Qr®j\œqh‚X~KŽVq¢dk„[l’BžšIÍ€ŒUœ^k—_jG…¤C}±M\®N„‘D­’fšð¦a©}Œ;i·yuœG`ŽK^=¹ƒ>¼ã•ïè«¶ÿÇI¹’’Q*v¶wÿ±LÿúÈ£•x°g‹ƒA®ÕWªÿŠpˆi{›[ä­R½µ¥Ú“Už·™³¸—“݈e“kdO:x›M¨§ZƒÌvq—Eb‡?\…3by:ip5|_Om‘X‰OͽQÅ¿Œ°S—“`˜£W—”\ŒZÑÄoÀÿ³¥ÕŒ¨èx¿}Iih]KDe\7aZ>r€A”’YnpB}wxÄÒÄæÿ³ ªT±¬ƒÆõœpEk‰[™¿‡¦Ý“œº¡³zŽ”b…‘M€g«w¨Á‡¶Æ¯Þ°Î³ÜŽ©è]`=_pCt„UŽŸd®Pp°E^G}˜Fat[fl¡d¢l ªb§·|›Á‚´¹›ŸÅpr¢VuŽ[rŒ@s˜]Š£q…‹OwcˆlfZ“¬~Ák“§r§µrvUiŽW‡œ]pˆUh—RPxA\iE{ŸI}¯^¼amšO¶ƒ¸ÿœÎ`i|7MX0L_';S,U]Aia7Mn4V{X{§u‚¸‡}£deg™¶­ØúÐàÿº¶ð’Ão~»x—Çg˜­vª¥ay–X_xUp„ht…^yn•©jˆ™W’œXi…CdzFIb>ThD`vKew_v‘k‡¢muŸZw™Rnn+HJ*HS>Xc:]sOr–nˆ¨cz‹Wor:uTA‰ob»°ÑÇ»«]}›Ge‡BTpCXeTjyj‡³y´a„Ÿ\„—KhwGqrFjrR_kMRkBQgJKlOYv?JkB]kYp†HcUr‘Qbp2€aR¦|Kª­V›¼r“±y}·{z’lm…Sw€K€xEs;ly?It61C4&0#M'”5îkGÿŸbÿî ÿá¸ÿÿÍÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûÿÿÿòÿÿâÿÿóÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷üy¥ØNK•mCHÓŠ6˜å“™žy†¨†¨^…¥‡g±`b›_‘„HX’=Zl@t„0†K‚—]]^yn5W•H_tGm}8›‚4‰œN¤¥f{ºna¤…hLo†EœTƒžRˆg}«S‰Ÿ`o“_§–[¨¿Ž«°¬}³{Œ£„†¢›Áas³yŸŸM“Ïo‘Ýz‰ÎhN™s9a+IZ%~f$ÂŒDÓÙv­Ë“h¼zV„V›–lldgˆ@hx?f_^|LbvJfc:ˆv>Z dWqUeP{‘W~Ÿd­¢r²Ú‚å–o¦]¹‰Hb©¦[D_y9|y;€O« \Z©‰¶«M€ÿž‹S‰Å‚‚¶e™˜R|®~œ£W~œ{„±\|´\¸©U›Ó¡×ŽƒÌ{tœcä”WÊ´¥Ÿ£Š¤Íh–¦n²Žzž÷½£v¬ì™§Ë|c»|t†4`^1g€DƒJ|À`nŸUiš=|¤@™ª]ƒ¤x®›]¾ùq_ÈtSv)Y\#pq7€‘B±…^º¯—·]±¿R›½y ­L“šN´Ë_Ëi±¨iÅÀ‘½ì»[Áy(^$&@=@7MWQxŒ*‡ª3?ŽJ*3'K3;oJ6³Š~r¨“…žJBƒTBJae._‰.9‰'Td e}GozRjSb„K˜ƒ?{¬qPq0‚x1’¨T¹È{¯ƒˆ¡U€‹G‘¯[ƒœWNt‰6ŒF{F—’Q’¦T€”U“šH•Âm”±j›²kžÑdÅÊ|éÿ¤¥ý–†ŒQÇ䄸Øn°ªgϹš¨à£s¨R›¡U‹ˆM—šn›Ê‚´r­¸ÑÔ®ÚÿõÍ븮ò—eÊQdt7^l=e`:Y^2`i6…Œjy¶WНkȽ•y¹f•ˆL–¨Z’aÿÈÞæÿ˒匃¿b¼z£É…”ÄyWi=X}7Os*Q†/KR*€zSz]ˆwuÿÿöˆñ\~žERs6\g3eŒ5_Œ-k}.—Êb…²?ª/k•5‡@Å›pÆ­hνhÑaÈœ–±]^;¡˜d»JÖ–e¹©cØÅƒØÜ}ŽKŒv[°¤g‹£Wx…c…™t›n¬¾…«åŽ”¿~´ü§ãœ‘Ê„®ËŸºäž–Îg”¥T|H€œT_‰M‚–p¦¾~ŒÀa~^¤lv‰XXv;ow[ˆ’u޲g¶×‘Î{w˜Xc‘Bn“@`Gp–\‰¦f–¤f¦ž~¬Ê‹‚¶g {‹¤nw”Re†1k{7es3Pc1Y_?Ro9Iv@bd ×­ò‘ªó‚ƒº`šªVaƒA®`…Çcœ´i´¤UjvBWlH[h?hz^ÁíÄéÿ©“¦Pjd8fs9Ma(CP6rnHTg0[yHz¡gª}­†‚¯jg Qn¡„¡Å¢©»ŒšÇƒ‘¸fÁ}ÎvšÍsŒ¹eƒ¢[pŒRy‚XgQf’b‡Ãt—Ñik”NfrC^e6R^=_‚NgqHS^E`pKYxJf|Qj€:Lh/K`5Sy9\€>\Sw‰exŽP_cCgdD‚\¯½u’™k›aŒKe~KTvFY„Mo¤]d“flŒvz•bd}PW{Fj{LjwCRk4>T2:X,hH(~T5jBžŽH‹µc]¤s=mf:FGb?"oV#g{EhpHdcH^dFYbJghCvkHwcFilFglIrs8f‚=”tH†™MyštnƒcGŒ_VdFEy1FaD`]3ca'ku7dz<~lGnsMYhW[_?U`Ii[Fkm1zC¨–Dw±h‰›xƒªkH§oBPSbR,\x9cb=“k<†LŽ{]TuTJZGrZ3̓:ÿÚoÿÿ®ÿÿúÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿçÿÿùÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿôÿµ³âZc¥84kA%A<9#QG)—`)[œr…rI‰b•±ixºƒ„¨kl´wp›gTŠF©i>™­Fa›t?zJCG2‚e-…šJ›]y”N{ªHgŽYg„GŽ’Hn¸RQ‘Psz3zŒ=f©g‰Š[£YU™k]eJzn0¥{xqžw‚Tsmž’d…ÓU|sl–V¸­KnÍŽ„…bŽ\V}Ga^8™x'‡ÆZª x·²~ˆ¬€ƒ²rj„]j}H‚K‡šWVv¯`g‰Uc‰Cyv@[žRiR“•T–žjm˜na‘U„TXwbª‚c}¸’V‘e]nQtw?WUMn;On6]~3™rAêÇ}·ÿÀç‚^‰kOvDTd1Yk)ƒŒ6sšiƒ£Hˆ¤` ­`¨Ë‡ˆ°—­®x§Ö—­Ïu¬Ùz³“›±rw~l®†G½°†«¿ƒ¹šg’tšŒHÖ÷xÄÿ´šÞ„ÂkkZIJYéñ•¿ÿ¬ŠÊt¡V¡šNÙ¨aÈX}|2¬ŸF†«^‘”]‹b@šc>˜•B¯ŸS¨»`•§b ¬fÆÖ{¬À‚Œs’y_̽ˆÁ÷¨`£}Ix16h Hd CV1_3BBe!/7#Q76¦5~®Onªb5D=>) MJZ¢^5PŠ[,Q”jbu/=l-Ob,|5r–NƒQYŸK¯ U¼ÇˆÅÍ—»áx©Úzjˆ1xvDd‰>lw4s|;‘Tš”Y„½[‘‰P}’PŽM¹]‰Æ`žªZÄÅm’¼ewO´Ìƒû²cÿÿ¼×ÿ´Š¬l¨‰n¼±u‘\—¤ZÝË€ÔßxÓüŽÐì¥Øÿ· ººÓÃŽË”§ºnÑÿÍÂÿšãÿ·­ÿ‘T…>bG*œ|cЧq‡³iŠœLUh+rt>~OÃÒ©Š¢pϱ‰²çœ´p|™Tq­L¦Ï|hÐJf}J7Y)wiPv K@l))>7DSk,œhÇn|yY‘•^v­R`w9e€5˜¯ay¤@d}1[b9™Ž[°§kÿ¬•ø³¢ô䪽ÃpÀ†fÿ¾ÿÿéÿÿ©Â½v”ŸKr«@z©_ßТßî–ÿΚ¬Ã|ޤjm†Hi…@ŒŽ~½Û¦Èÿ¥Åô±Á歫袙½’”Ç€}Œt’¶u²¡^}¡H]…@pz_‚•g{žMfˆ>Mb5ZX2^t:cT6PY5_]CfvCdufphg®‚^m¢ErŒQ‡£_аo—ÀjŒ™w°À®ÂÑ|†¯t‘·y޶ady3Rk$K`#E_-V€HhŸbt¡g‘¬ŒËõÇÞÿÂÚÿÂÎûކ³U¼c–×}žãu§åœÙctˆ5V^/^a9t“n¥¿Œw|PfsC\wDmŽP~Ž:]d7aa/OS>„¡}¦ßt„§s|®|ˆ²m¿w’ÇŠ®jq™e…¨ks’Mq’g¼iŽÐpv”WUuRs‚UŽ–Rz‘U‡¤oŸÁ{»es‰=MR6[Z2MZGiuPVh:JN/@N.BI1B[>gf7^p1QsM{ªjŒ¿joGRe8Ld<_l@ux_©¦sž“OYpH‚}Had;NlF]z[y¨v¥ÛvŽÎn€­pw“Qe|;_|U˜Œdv’Weƒ?Cc*5V6=Y=HoVl^gƒ]qvšÊx”ÆxÄf‚¬IXs5Ka6QlNBF6WW)_j4YE]kT—]B`wA\~m`y]LvMRVCcP2y[5zvEŠƒZŽ“`‚§s]ˆ‚?`c3B@H8)l=!Uv3VbIUf?Š~K£jbª‹YÿÃ|ÿó•ÿÿ¼ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿýÿÿéÿÿüÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÉÿ¾³ËJs±39o90A/,",)¡%ív&„̃f€c’„D¬Çl„Óz—¨z”—¬ˆy£{„£rfªY{=…¯UqÃq‘Vp GŠžT„Qq‡RƒšUxšW{‹D”ŒI—µT[´`b}SZ{5ž€G…´ns¦b|‘J\”d_tVi„/¦ieuÁga|sv=ÀœYeÿ{‘Y³¸[o¥o“xI~„^uŽQUh?yW,’š6¢¬pˆ±d—œ_¹›vœ¥{˜¦ji p{ŽEn—Zv F|›^[‡aboBl…TP~CKp=MQ7hU)Q‡9KG6CX'dg.‘˜P²lSSOh>Jm3Uq2^h4fy?hŠKhˆBÁzF·¿žv©]ŒYX„8jƒ,W†Gvw0fªUh‚E_ƒG]tSŒ„@`¯lª:¢Æ‹w¸•Ž—[Ÿ§{b§ ¨vH„¤u‡kD¶ÚgnÖLp>Žj)Èáx¾ç¥ˆÓŒg`RíÂMàÿ´Ôÿ™ÏÜŸ¯Ì‘f—_s_8°z\»²q|‹[вPŒ›\ª€Cs™S€‹A®¢E±¬]®´n—±Xw™MUz8Cs-–{3ÜôxíÿÂÄðÈqŠ^«ME|0DX,K(,T7&BI_rªš[޾nL¶Õd™÷xMåKBGSY(e‹_N`&Pt$uw2­åc¨ÇxÁß}™½iœËhŸ¿mó÷š|Ùks•Jˆ€Aµ‰N³½muŽPw}9y6q‡2ˆA¤­WŠ”ZŠ‚F†’Iw”V©˜`³Ä“ Öc´Qˆ™Z©›U£¿`ñôÿÿÔÿÿÿ¦ÿ±¬~T¯—y’„D «RÉ܉°¯d£·š¼u¥Ë–­wz¦nˆ®vŠ‘SàÕ³÷ÿ½íÿߎ¢xUN.ˆS`‘­x¢¹Š{¶Uk™C{ K{zPi]A‚ˆ^˜°ty¥U¨»XŸÖl¿Yˆ»[“Ëq£´ƒr°=Zz8Hv,YY7=J,4;GF.k€F_s7‹‰\j™EXg,xBwu=‘RxIxpAw}9‹p=ß‘kÍÓu®¬c¦›UÆ”güätù^ÿÁ ÿ᛾Êqٺ뿪¾`„«VÂfÃÏŸàðœÎÆ}±Ÿc…¤Nn˜>j†B§¹‘ÐìÇÕéÈÓø±ÆÛ”«rh…DrxKgdmyIr‚Gl‹JiNp•J_p9]n>_‘DT};krBZd1}u8£ ^b•5Db&Sy,Eq-Sb3ceR2|yx™¡wo|Peg‚ÊñÇßÿÃìÿ¶¸ä~fP\yX…£|¤Éx“­v“ª_pAsd5tuR™¿dlˆ9Ka.QbCƒš\u®a‹¾`b.EG,YeR¬yŸ¸v~¬by¬ewŸgn”u„¨jp‘TlŒV}’Pdq9a}S…§o¸giˆAj“[¥´TWy>*‚5ÏU& ¾‡u©•šlM‚±€k„›vFšROUdW:qŒC\ŒG~~Eˆ’Ikšr€…UŸA›°k|—m“ŽK|©Ix™[™šZ|L „7a¡nrpJ…™9t‘Nw‘Tb’[s>d“SˆTj®N‚|i¦C[µštw?ÅE€ë—‚žm€[†‚Hž~A`ƒ`p7k˜Sˆ…Bm‘UyzI‡ŽP|O™ŠM«¶q”¶ƒ~µƒfIo„KeŽMc€Mh„Sk>eP\{DC?Ed+iu)¥g1Z€Yt†=t”XgschhMC{G9=2ZT%?m7G_(c|'qyDš—Og½f“‘Ac‹mM€9ey4nƒ7Y‰AZ‚9`w;ZšEs8‹¡Wu‰xš‘ZŒÿ‰‹¯cj¬pjuBh…K[‡]ÏŽD€Ô’¯’V Õ—Ã…º³f—ÿ„‚©l¬ÌoH¹pl> иkÎÿÌàÿ±qè©6EAlb$|¶Sp­>޶Oy’M’¡HšY¢ª_½®e®¶o·Ãz°Ý‰œí‚ŠœR‚§Dl¢9ŒºLËÂsØÛ˜ÿÿÈèÿÓ­þ¹k¬zI”F+U"C;)]$M>;CTxVt!Z‹'BY-pu, šcÒÇ’æÿÎ¶àˆºÿzß[¡Òkv×_u¡_¨š\r…Rª¤p¥Ù˜·ä’¯ã}¹Ï“–¿fœ·c…¾^“Dct1~/‹—E‡‘H…‡:¨–N™¦Z°¨\žŸMÒ˜aTMƒYB ¶d—±j‘©S¨¢Z˜·e£¶j¾à¥£¾tó¾²¥”oÿá‘ÀwŸŒIÈÅoÈÖ•®]œŸh³º‘Ž®f–´e½ÿ¸u¼S_ŠDvŸDƒ¥Oz R~fE¬¡Po¹OSU5‹zt”´†† h‚©_oMFV/pOGáã·ôÿܶç¢g‹F‘h¯}г­˜žts·¤†v’R´½Ž‡ÍWkŠ;‚žV¥ÓqÛÐ}‚¹ab†E…yVª‘m™‹TˆN‰ˆR…ºU‰µ_š°gŸ¦b ›pœ‡]¨˜^“«TÄ¡q溃󹂩®a¾×|‹Ç^¤¹bѦ‚ô›ˆ˜QsƒP¦­…Ãú¡ Õx–™c©¡r†³eg•A‰jµª€©s‘ËdZ—BjªP§àxšñzu©StŒM™ÒefŸ@n_ƒš[{NsSƒ™{šÏ‹”Ìt“ºpqŸPn•k}­r¹u—Çvo±Vi¡Vq¨M`H^pAk‚Fo{C”³‹—¹…’«®q„¨Z_|GV\AmuF‘BNs8C]8bZgeÆÓÖîÿàíÿ«ªÇoQa28:2RP3Qv1>Z7QYIXcAymKœ–fšŒU|nBrm9^i@sqa —~ŸÃ‡±Tw|HsrNl†[uYq¤RhžPUQaz`‚™iw•M]:HpAT}Kk—e¾†–ÁnkR¢´…öksŸRi–JTD`sHsxCgV,ZP-L]5X\2HJ1SV8VaA\nKd|DYz@VhARa5SYC{{XhtJg{F_ˆ@YuMapNlzOmi;PZJ†yO}e.NeAp~Wƒ°awªlq¦t|®y~œJXuAQpGW~;QkDRn[uc¤T]„4Af9HhL^„l‹«‰ªÌ«Ì硺ߘ¶áˆ˜ÁHUkD\wKUzBLMF@J7985GE,dP/V].@M8L5CMS+Ie88_5LF/^Y*bd9ssIcfNmnR^O`‚`iq[^dClcBao3Z~AOqGXSDOV6hL8c_7lF‘|DsˆYzkc\|X`Y[oZ<`q7Qh9VJ/GI.ZI*dM(^g>li@zg=h?zgRŽw=¨‰J‡xEksPj_@wsAf€Rc~[u‚Le”H[‚^“gB«§C‡Ò„‹²{ÿ¬pÿö€ÿÿÔÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿúÿÿóÿÿûÿÿâÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¼öÿq£x8N…@(PÄ-!ÿu,ÿÑÿÿ«ÿÿÿÿÿÿÿÿÿÿÿäÃíšg¨vjL‘H€œVbi@ksDއX‡¨`[©y@€LJL$_\+lq@p–LX’QmJ¦JŒ¦L€§jycvFr”Wx„QŽˆOr@«z?vÃo{ŒLw‘D…€_hŒLl’Nq~EmžQ•¦Up¿hx¬p¢§Q}»”sŒi»ŸSl½|fmY˜[;}ŠTªO|–b’E’«cr§bQŠOkn2–„6{“Všš_›£m‹¥rƒœnS•jbr5ReHff8i„Jr‘D¢›Rr¡ewcNƒvhXr[‚x4y™ZXVkhfB9”l[‘¥\€ª\„œUHg5V—<^x9ÅtŸå‰ŒÝzŒ£Q”’jŽœwœÖ€†Á`dŽNe}C‡|L‚xM~\A˜‚Vƒž_wŠra€K”‡Zº™iÉ™rñÌ„îདྷmû‹˜ÿ³ŽÄ쀢Òl³l쇠Äy’¹t ¾”¦¿|w…c¸¿£¶Ü‚Õʼnÿé°¢Gu”M£´gµæ•çÿ¿Þÿ¾ôÿâýÿâîÿÕíÿ®¤êˆ«Ì‡…¶O|´^t±^_žRpœ\Ÿ¾z‰¾Wh›Jn›[x»p“¶„³zde«·¬Îñ´ªÚŒy¤U`ˆ;fy@nŠH¥euŠ\‘™o¥¾|ºÛ…¦éÁú|™Ñr•Ì…†¸_‚‹UbcT‹Žgf{k±™ÂØÑžÂܹ?=H#GH,Qg)Pk=nŠQm‹V¦e¦°^c`0^a?fh=phK‚m]}l³š©åzz7O[>rˆX{™ZwŸWp‚BI[1HS9OfGcCe˜Oµo“¼‘Ä•È󲟾Zw”oº§~ž­l”Õzˆµ\|ŽMgƒLi}Gnr4Ye>gvAwo<[^2V\0FW=MdZo~RbpLlnHij9NaKuS––Uz²^v¬\v—\mQ^rDkZCaL…j?h`2Q]?_qTnšrÈl‰¸ct‹VgsGShBUnM[m8EX;PnQe‹bwœhˆžM]„CUqL^ucu™y“½’®ÑŠ©Î™½ð‹µÆScK_NmŠOIPT5:4,/.=,'DJ6C*>9)S9#KM)PM0Kj6[e4`k8Sv?TgOVaCv`B…v9R‰œgfŽfeydfhCiHxUnyVwRBa;m=‘–Q‡~[–}X~zM~pTurEZjORV>GT4NI+W='`H6XJ,fU7d]5~`Aqd?€_XžjE¯L„]JlVRZDq\,b‚Mp|LzD‚ˆNx j²šbÿÌeÿÿ©ÿÿÙÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿúõÿÿÝÿÿ÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿíÿÿ²±õ|.Vg%&7)&B¨)ÿg.ÿ΃ÿã£ÿÑÊÿÿ£ÿÿÿÿÿÿÿÿÿÿÿÿÿúÌ¿ |”Z“†Bo‚GfaJlfCUoUhM@fN2Zn8nm=No·sŠXˆ“e€’^vŽce|XRqAciHmy;`~6dx;ºt6¢Çt€”V‡uEbvApl;ކDo—_‹ŠQ¢«ZœÄŠ™ÀŠ£¯s~Âj{¢lj]pŒW“i7™z5{X…`޶X•…Yj®sjiHR}Fck7„<ìáW¬þ¸y—~—‹]i sq’Q^•Qh~;^r6\}=^o7Ÿ~@€—eK˜^L\-bo4{|?¥fhzVn9—‚T__i\^Prt5UzXv’;Û¹]ÿ¨~˜Nˆ\€™T¤“NizkY}:B{\‚Rtˆ]‚©t’³o„ªa}‹S£‰^¡ža£PZ…HrvErk;rm@hg7hd1_g7MU0NJ3hbDo}HXsHo‡_z–_¢oŒºu‰µz€¦b`qAcbKxtJ‚‚Hkl4ViGoxMntXp€OTj6GM4JZ:AT4AU8AY3E^EhŠRmŽRe]t“PfŒMi‡M_~R|“k–·iˆ­oŽ´‚¨Ð†¥Çgy¨VqžYk‹NFQOE6:61-/A<'B>'XJ&OY/P]7Ll9Y_wg1†V9gG~]Cy^=w`MlfD|bC~=fZ…xT•›HÖ¥kÿ×}ÿÿ·ÿÿíÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿßÿÿýÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿfæÿ`?}-C>03%"& 9&ïn*ÞÄp«ÍŸü¤’ÿ¤]ÿÿÐÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿä¬þõ pÓ–As\B@-A=$AP$I`*U.¢‘?€³deoHjKgJ9‘o4sˆYqsY`lFdxL|:q–=d‚?¯t2“°^‘[¤O™•L XpœZ~ˆI²—UçÀZŸ»Š­k——rn©alwxhŠC{~Fr@ˆnHs8~”[z¡g“ŸU™l¹~Pp|g˜y9úçf¢çÊŠ‹³bJ¡ime2}–K²cÂj‘χiŒ‚g^C‰„UfV‚zKf¨mNVJ–V/r½‹’Xž€^FIfkM3]e2Vi2q0œI›£}ƒ€yv¢fR†R^s=qx@L`DGv-Hj(2S,TT"ey.RvE[^2hhGV˜Jcm4–—FŸžp™Íp]—_\k8aw7Yt<µˆ8®ó|“é›N—~pŠ>quCè«E”ÝÈ|¦k…ËOq»`ªD†¯J}±Rƒ«f{V^´\…z‘q?x“ALILcGfP6nl0`|`IxdTZNl^:zzBpƒOeƒVbkRnlOj‰O‚]nŽ`hj\eb:ok8{d=…iE„tG‘hJ¸ŸL‡Ükyž‘ŽyW•©Wj”^hZSh[;r`9Sr9wG>qa-~ZFxb>raH‡qC‰›Jž…Y¡“N– a¤hÿ´fÿðvÿÿ½ÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¼Ãÿ8rØ$0‹^ !7?!23(#:#K<QD$sK$¨wL¯Ÿm¢ƒÿaUÿ¶_ÿÿÕÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿýÿÿî™ÿÆ}¹Ž«[‚ÌfÈÇtÕÿ…ÿÿ¤áÿ°€ÿ’c±qÅŽJ€¾\^†g©\3§‚I‹ŒW‰‰M‡¡P½šAÿàVÿÿ´ïÿ¶ÿþ¥Íÿ­œÑšÿÇrÚÿÄ¿†~¯~‹“G‚©iœ‘Ps­ŒZŽKsg:—¡:lŒ^c…=z–H­]“¾f”»uh¶…wƒC“¦Ešœ„Z“zŽn?f‘YClQKh/tr0eˆVƒ‹Ttb_^bg;’hzPXP+dŠŠ©W›v__€D¹‹NÏó«Åÿ°ÙûÇÞÿʯî³Âz€”ry[QŠ{_‘—e’Úd¡ë‡}ÁrlŸX{•Jµ¼yŽÔwf¹ZLo&g~KB\#Ve*c…1’›B¶ë Å÷w¡ï‹´^¾Ñ—±æžrÙd–”s‡¢[}¾r^ŽXIo=nN4•–_å°‰Âÿ¯¬Ûxÿß±ÿÿü­ÿž‡´f«ÂxºÓ¡Éó»Îü»œëŸe†B‰ƒM§¿‰GÂÄ|ƒ¡Fš¶M†¥O²…VǾ|•ápšÆ†ž¥´¹‚¡Õ…§}£»x}ªad…<“€kÊé³–Ê€lx>œ§l’°y‡½m†¸x­ÃX‘‚U¢‰lŒ¥o©ä†©Éx·â}ge>vQ^´“ˆ§¬‚¯ÒŒ±ç”½Ý²à÷ÄÚÿ®¸÷•¯ñ ±é—£Èyu®d‚¯s…`”ZoŒV’†·Ìx‘žP„¬Yx¨_mŸ^£Å„—«‡ÄÚ“”¿y“¹q‘­zƒ—l–§y¨ Ž²Íš¶Ô’¨Ë‡…§]Bc%Li,N7PŠ=yGS”:Qq[vfsg…E7X;vškÒ–·‘¥» ºË­¹ÙÀ¾Ñ“¬Õ}Ÿ»k¡šgž·lŠÂgc›RTWq˜€·ÜµŸÓq’¶w³Ò‰…®ZluP‰•f”¾vÀi~«„„¢_]k5Ug3Xi4[e6mn?~j:khL‹sV†§a}ÀWq¤Xh•Ju†[q˜Z‹T`’Ms‡MˆvWp{^bWp†Ym–KazCZd=^o@`g:Pf8axc›«~›¤d€³iŒ¯jн^v–DyŒZ‡©fw¨i„­g¥hv‰i{š_t‡XqžSZ9Cj0TlK“‹cޝišªZ€ŠDUiOiq[i|Ma„?W}8KxXtŸ‹–º}À„Ðy‘ªj‰[ƒR}uLsƒR}‡Mx‚Bkk4Td8Vb5B[CLyoy¦o„¢bl—@Hb@JaBSk4Ib3M_6Olh‡«‹»UqŽOjtQZtHVu=Jb8?Y+]p@cl?X]7sRCri:`i>fkCgtEtvNk|PNvOK\VZJ?Wg+\[2Bg?T^M^k;[e;\d;lz@ˆJm…T|tTy–Vu`nnXulDˆ„C‰‰X|K}ƒN¢uK³œHŽØ˜«“¬¬l‚Ót~’trpQ‡rEŒƒA„uK‘fA‘n>‡mL‰mM‡iP­}K´®\Ϥoþátÿÿœÿÿ¶ÿÿÔÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÙúÿuµÿX‡¦Bzd#HD#&B 6.,4*<-j?6f,6J3LM«f$£´Sm¢š~d\ÿ?ÿÆqÿÿàÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿú¸ÿˬ̂ïÅuÿÿŽÿÿºÿÿÄÿÿµÿÿîÿÿÿÿÿÿÿÿÿÿÿÿÿÿöÿÿÿÿÿÿÿÚǦÿ¤‰£nvœm©‡Qc·lo~N“‡Dºª\n͈¡V¸O¦ªv’¹˜¥ƒ{»}eRikR†GxŸ†’ŸWMpehb4o‚7[p^x‚?q‰W“–Yr˜†T~LZoAZe?œ“K‰˜—™Tä•iíß»š_sÔ~^nmÅc?\Ÿ VXF\4J_,Me0R^*Yb0Qy>tv%ª—PÇ…y¤b±¼MÀöŸ™µ›§ÿ’z®uR‰D‹{:…Ÿjw¢mKhXl†K^ŽB5tÂfv³_GpOas1[~;‰Œ;н\ZœET8yl;r˜\´`”›k•­j–²qŸ¢w_œS©;¸ÀpÅêwŠ«”‰•VV‡aUZ;jq6¹Y€à|r–f•Íl†Ãx’éz‡Ìe¢Àb¬ÉxßÉ‹Àÿ±¢—[a§j,A(O"ÿƒW‡ï¬]bGu£Nkž@ƒ°KwÊT“ S‘³|~¨j”»U¤Êc˜×Z•ÃS“JÿäìÿÎÚÿ̼÷®¥è¥Å|ŸšYª®qÉã¬ÃÞ·Õ羱ߤœÞ’ˆ¼r¦´kÝäÏж¥¯À›r®yj{D?‚8HY%Zy/Œ€Dðèªÿÿçÿÿÿ¹ÿª—¤WÌëΩù´¡Ó†»q‹’L‹§az¼^UŸEjkY[~’gwiqœbi„]c„Qf€Mk„c’«ršÀer—Vm†\•ev’`o™qŠÁu¼dŽ™O€ƒX}n‹ºw–Âr‡µWev9M[5Rg1Rz+J{/Is:S~Ulˆm†¯„š´v‘ŠXŽpQƒsGrHp‚KgMdqEgl>^pIbŠKe•WcŽ_f‚[^t[dxDK`-BU/EX&AY(@T0H^Pf—…¸Yr‚Gbj=[d4Oq?^Mb‚@hcB`t;€dAt€IEXC[Ts@?mU2Me=@O=<=49B:@E9:@,KF)u[.t‡HfJblE…sD†I„¥Yi¡qsbi`„Ltib^i;nn<‡s?‘M‰‹VN—˜V¦¢S‡Ð~©‚™œi‘°o«£z¬Z°d”\™zaœyP®”N³¼c«ªr¹‹bþ´cÿåˆÿÿ¬ÿÿáÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿãñÿhŒðP¥{Žr~˜rƒ™iSžr+Um"%)$$/)@<^F Ej07cYBV1cW*‰‚=‘k{zh~Wåw?ÿ·Vÿæ¸ÿòÇÿÿúÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿôÿÿÿÿÿÿÿÿÿÿÿèØÿ² ¬ž“¦l{•h~”S‰ŽHˆ™Nƒžb}¯f™az‰J‰ŽXgž_r‰Tb™PžŽK‰˜O¡‹J¹’ofœjGiNP\'Q^;KL1Y]2bxF¢l>dhZƒDEp:LY*YN2b^FËuKбqÙÔ’‡\^lfmQ vKY¤q]f>tq7wtL†Œ^c—ppeE_yJY—L\`0UKJm‹7O‡>fr2¢Fx`h‘[b|7`ŒAqpJ‰‘U¦œd¢ÿš¥”z‡•‚j}O^‹Ol…?T~MQI6VvAâ…HþÛn©T‚¡a|Çr]‹ICz>TN&qh5½J‡­yQJVk.ƒ:¶m¡®f¼Í„‚·wv©IužV§§J›Îm„[o’HŒ„G—äšT§áp Õzt¬qq’Xw¤Vš‚L»Æ‹Ë㵺㾎ی¸o£µƒl—\IE6DW(Y]&˜–BtžfŠšWÃÚ{ËІ®™}šXs’?¶ÅdÃÿ¬¯ÿ“Ëê‘Þÿ¶Úÿ¹’ÁwÏ×máÿÃÓÿ©Æÿ½¤è®¥Ån–]œµ\‘»{“®{›¶¤¹†¬Ë‰´Í‰¿ß±¸Ì¸mž•rh«a`£JgˆTFl9Zi'‘Žm¾·Øú©ÿÿÿ¨ÿªŸ¦EÂÝ€„´7G0x4(Êà‘‡{Xº½¯x¯‰r•J¸µsß¹~ÙÈÑ몹ۋŒäo§T‹¦aµ­|®¹‰s™;…¤\aŽE}ŽC ¨i·¼pÿ›¨ÿï­æ­pÛ«q϶sب‰‡³lŽxV„–NwvL”`®Œq{šSœ§c¶²u|«Lf8[†5Tr.\w1Um0¬p±¶tvl=Ë™…áÿª†¤O †bl…?“¦` ÆhÖü›Åÿ•Ïà©úÿÊëÿ·¬ÿ|´õuž¤dçÿ±Ž·sb‡IUvEžÆ§ØŸ“´‹›ÁÖ쬓¿^R€/RcEƒ}S§½j·¼ˆ˜Ôh½µŒûéˆj¯SfLŠk™›fy¢PO{38R$/MZ=Pq+Kn,Kr8u¨a¥ÐŽ§æ›§Í‘’½q—°¬ì˜ªØ›°Ü¨°Ö˜‘°|…¤y—»v‘²y£x¢ms‡Zu‚Wiz[…wžÊ…¡Ãr›Â{¤ÀˆÐ·™¹‰Á÷™’Ü{z¶`VJpzX•ªs¡Óy“Ín€µWqIe|wD€¨Iiˆ[bZxaI|B“ˆ^y«b\•zRZ\XW8d`F\h;WqGsY8‚d8„yJ“ƒR‹¢a—¬r‘¾q€º…‚n’]¿‹RÈ V®¯u»–oä‘_àÈnðåƒÿÿŸÿþ³ÿÿ³ÿÿÎÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿž”ªY‚¿)Rj9(0M<"`G.Ž{Lz³m+ˆƒ!-L &(&>0Q=…k=‚ ^ZŸ†]h^bjLEaKZ:GaE,cuK”m9Ý‘Oÿ€rÿàÃÿÿïÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿòÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÍéÑ—Ÿ¢ž©Sƒ³t€Zl“g_‹M}{EiŠRc‘[y˜O‰‡\rŠWg‡P‰uO©|QÀoŒd{UWhHRk8X[0UR1RX7el6qŒC‰E€‘jN¢YIhAHb-SR*]|<žLµßptËq©gbC††C»Y¸§^~»c‹X{x?syVbvOs|A´­Mu¸Œf”`azH_|Bl£IxQu¨Z|ŽTk˜Yv†CiGq5”´âŸg|ÿÄe‰]`¢C™‡5a­rsyGg˜YjƒKem@ÿªYªÛ¹­z~­n|“Z†»^_Êkm•JYQ_[5€™?s’Rh•P“‰DÐÑpµçŽ·Öš“Ó”ÄÌzű¢›¹‘o„_oˆ<·–R™ÁnæøÞÿÈÿÿljþ±ušW”´K“Ò‡ƒÃh—¸ižÂ…‚¡}ˆb‚P–´‰a«mKc;n=£©G¥Âf¯áx‘­t¨ºtiŸ_†˜Jr“L‹£X™ÇnÄÛŠ½úÚ¢ý±¥Îÿî•Ë‚±Ìyðÿ µö°¼«€­ñ¶¨¶‡ÿÿ§¹ÿ¬r®hŒ•j{šk–°i¾ìkÊ{Yƒ,[\*\I.XQ%s„B„xOFeåÖÀg`Ez€M}SȾ~âÿ°§·{š±ss–gŠ˜PŒÈSk£;q‘Bh‘=xxAd°Ox|HºÀu×è’²ß†Ðæ—îÿ›ùÿª õ‹ŒÅ`¿¼bÉÏw€•Euw8gw6bh8v}E„•Yy’I©žq˜•s‹ƒUŒ’No=b‹7]|6`2‚‰LŒ€^WB3ÿ—¬¹Š¯Š}“š^nx5ŸšPÞ·‰ôÿ½ìÿºÎÿ ½ÚŽøîÑðÿÊÀç‘”¶T‹œS\p>gnB„¡`{—[“¡n©ÂŒ®ß™Ëܧš¹ee¤@Vw/wyG•“`¤Ák²À‘½â£«×–ØÚ£ŠÀi~‹Yƒ–Oi—VIv($>%9:J+Ru;>k*-I'_Pf±±š²½“ŒŸ{œ¦r_ƒ^·²•œÌ‘›ÈvžÒf­N[yHu†LHm4avJlŠ@`E`¢@U‰/VqG„«kk;`‚>dlL†ž~‘Ð}žÜ¡®ç£ºæŽÈbfžER‡?RwAJfD[{h½É~ÒaqŸH‡š_}¦‡—Ñ›·íŸ¿ÿ‰ ëŸÇ…£ÉˆŽ·z¨xš»ˆ¦½Œ’±w–¶›±…µÑˆÆn†½z™Õ™ªÝ•–Õ‹™°}•žbxYp©L`’Zršf|hƒ—ršÄˆ›Ò™Ì€¦ZnVmŠKp–X²n|©xµ‡”—ƈ·z¶|ޱxŠ cy˜Vc€_m‹Wy’J„ˆFop5LuA\‘bu­^o™GTˆ?OpMk”^x©hsŸa†—XrˆMe~Oe†K_x?atNdvXd‚^kŒQ`{>Tf9Sh>YlDTp:Lb1Na6Pb2AYHWybh‚loŠ^[n3I^3Eh26Y9eZ"yw?·…Mÿž`ƒÝo{Š{b‹c_h[j\AtWJXnMRxWXXSho5j‰@c‘]_tXxp>˜…CžUˆ´g‘—g¥œnšªq‹´€€–~†WšjL€S˜‡oφkÿÜoÿÿ°ÿÿàÿÿùÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ³°ÿ}nÏVg•ESC<@?)408,%&6 h* Œe'Rˆc(Pj.,+04/=!-6 d3x`(p|aiqt`oc3XC"27)c"gn3k1®†Lÿbÿý—ÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÜâô—Œ…•\¨Vl b“oI€¡MiŒ[‹˜NŸ­fš®ƒ`–wq{DeŽUeŠH€p?‡’I•bv‘_XiSLj8Cb-RL&>T/BF'b^.]€;NdMSe3Tq:Vh=Cq7k\*˜˜B“ªom¥w{{^|˜[}®n{²b•¨S¥ÃssÂ{neS—\Z{Ddq8gp<„r@ކMèÆ‹ôÍ„ nw…eˆKN~Sad.pˆDptK‡‡Hÿ—f‘ÿ蘇]‚§r‚–b™±šÊœ…Ài–d‘‘<Œ×m ©cªºg¯®oÉœqÕ˜h¶e©ŸA‡¿‚‹¤rJ‘SnX.|–Z½ßn˜½“‚ªk‹˜Z•分®hl¬Y‚‘H–«[z°aš¤Qp£`P~:\h+‹¢K¨µhšÍž­uа„‚©S¢°\‚ªc};ϧmï늪ÜwËk…§Z§½r¥×ƒƒ»|R‚@Kf8žqF‰¶{¶}‘°eˆ“JÃc°kØËiÿÿÀšÞ’da7n›S^u8£Réÿ·¯ÿÅL›MOJ$ZH(IE!‚b;|Oi`OhBF1ll3f@¨¤t½¿ˆ¢Ñ|~Ñ|D7p]H†Aÿ™f¢õ¾„gœ­…¼b”Êeí飱éšcˆWas>w|H‹’\y±MkŒ5†®C¯ï{íw|›^‡ŸW§Ûjžåˆ¢{̽ ºÃ—©–j“¨_ïÌŒ×Ãi£®n…Fy~L}y=‘Vé¾”¸£¢¤i‡ƒIq‚9ln3vufg8CE'OW,uŒYµÇ𥯄¯m}¸ltŸQp‰A€xK¥¿lx‰J•—‰»âŸÇ¶ŠÎß‘¬Îd¥©o–µul¤G9i)X‹Ci±Sp£dSv9\nYO<)NX)_X5€l4´vAl[dwkZmOSaP[S7[S4l_9m‚D¢mP›ž?Àt_Ÿ‡iabvHˆ•Zƒ†mw•fp™m‹pN„rLj‹\ut[„~S‹‰QÀaÿ±zÿÿÿÿÞÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿÿÿÿÿÞÿÿN·ÿB@B04r;%Oi3AB61L@50!,;-4 01<2!!00/'=(N9YX,5\8;B0CC4O-U9(B;+=C-?M/'I'k!ej¨u5ÿÃ]ÿÿ¾ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿôÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿŒÿÿxŠt{ŠO};g¬uaw?r9‹©U„jk®pŸzaœ©nqÃmc“TQu>KkBwY/{”Px€^q…NMyWHy>6R,UL*Re4Xa<—Œ8X|U[i;]o9[e6Tt6Dj5oj*›NŠ¡v¾xŒ—a«ÇqÊŽgÁsh’IWkJ¥{?ËÇyz•­Wta~nAyžUmyPRwLjo8‰ˆRŒhr›j~—Kt©kt|[~S¯‘R†›g|UË­id¿°c…UƒŒKfyLNmCOh3t‰AyQgŒOÿ•FiŶò‹Mšÿ߃²w—žuœ¼£]Œˆ…B¬¹k³¢}˜‘_yªm›[ɵr¡—„u˜bÄŸS˜À|†ºtw’RqWtBc…PTk>dX$ e?l‘w€žTs­SlšRnMe‰f|§{”¾w¨Ua:Gs8Lrgx¡zФjƒ¥a¯o…³kz¥^k„M`‹YfœYY‚RNo?D].A`,AY4Kc\iŽj~“V_{HXpMfkMxfEa[=CUP\wThzAXb5KS8^[@edKRkGZpFfd7w}HŒŠ_Š›cežmaw^eXDZNBKR03Q.N=.]L Pj4X`7J^0MU0dR4fk5xm`~Hu|B—›X‘žiÄ¢VqŒv—wGêizÿÎLr@EJ/^p5’}D„ºp|ª^oygwgOÔi=–à› b}o^†Žbª§Xt¨tdŠBSwAg;Zz@Qp4CX&Hf*iI)vhIz›Zj­Gr•AbšUurBªwe¤Fvv3¬ÓvŸÀq‹½mu¨MrœCUª=tx:j{:œN™ºqŒ d~˜g”žK\…9Nq5Yl4p4eŠ;z„>£¶†q¡s“Y„¯]}pTbD‰r)¨°X©Â]¿kq–UlxE˜Éd‰ÇhŒ¬NžÇ‘K¦E?c'YO&g?…ˆS«\uÌp…‡U­»‹ÄÚ ¶èµ~›k«“VôÿƒÁÿœ€«M·“móÅÕ…ê‡ë§¢Â•j~Lª`¬˜jQ|;„iDs—M¦¤m¬Ð‡§Æ…[Ÿ:Sw S{-Te'™ŽX¦ÊˆÐÙ³矤á«å‹‹ã…~wQ•¾zp|5®‰cÐÛ‚Ëޤ׀|{Gr‚E‰ƒQ·•qÁ™ƒÛŒƒº¤p³—qЇVŽ„StŽIˆwVÆÆˆÿç·ÿÿÂÿÿÂÈÇŽÿгÍȆ{ªV`a.Mb2Qq4rKvµT[h9mƒS^j<=Lcb+y¤C~Í\œÉ‡Ÿ®wjžFR}1Jd2pNf„H²Ë“Îÿ§¢åƒŸ }²nž°‘»á¢ ¿|šáƒ¬Ö†˜S^yCxkS¼“‘xŸZŽƒ\¨¡r¢º{®É‰âñ¥Íÿ˜fÍVyym‘·~¡à‰§÷†Ÿâ~“Ôl©X{‘V_‘??l,=Y?–¯„¨Äq{£Na‡4W‚/R‚6[yAu“c‘¾“ÈàŸ»Çtx£_¡Ç…·Ð…žÂdi‹Lr¤LY—K[ƒi ·™ÓÛ¥²Ö{y‹Tq—Xn]i›kŒËka¥?>p0*S!4R.RwRn‹Wb†Oi§q~»pv¢\b‡bncz’h…•_sŽXz¬^o§d}“MpzMqŽ]s‹Mag[‡©Ž Ï› Î®à—¯Ô™·a‡¢[‚¦d“Àv‹«]mƒh†¨ˆ¦ÆˆŒ¾™ØŽŽÅyu¨aY›mz·†‡À¸x޶yœ‚¢›|šžr”¥iŠ¡Nk…8La/Cc>Mp\kŽb|by¨Zd–OQ„ahiebq™i€¬oru…ž]^t]\‚q{šjiƒZ^wMWxC]wCTt>Moaq—dt\rŠGbeBhX>h[=b[:WW>[iXu„NpsFdiJeoOsyOvR2h”9†ˆHŒ”Y•kƒ›|Y—vdxigfFarJTeB@e;CH9QJ%H]'YQ8]c,ee.en@fuFcrDhxMp_Ew`DDjGHMSNM>X_-\X5lX5†X<…o<—jL²…WΤjâšhø¢rÿŒtÿÇzÿùÔÿÿñÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿmxÔi^P‡lPˆ–Y¨Šdi®l-†­166h,1i3\25Dj(xMR~j$Z6/}AE31(B?SO+pN+q†BDvECNMdH+B~HAMFAB%\O'ÿ~2ÿÿ‡ÿÿîÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÛÿÿÒÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿôÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿíÿÿ¸®´¡hj™gŒƒVw™Y_^©wMW–XŒnAt‰BmˆWZ‹YMh>ŠZ1¦]h^\Lh9MT>hN;rCŽƒP‰n_v©…z˜OjœnP“^Rf:Je)CZ0]X*W€F_l@Q]@hf6W€Xdp>ª|>ŒÀ{“›djaeFBcA`X'mqFx•P}wJ“„J–‹W^uDzu1]~EMbAfp5Q|QX‚K`€BQ~CL„FYg,tF2ªeI¦ûœm°‚¯žMY ww9…yHo†b~p:¬¥TÝÒ‚o£€kzP`oGˆX?¼â™UˆpƒD›¥N®Ãqšã]whds2r=æ§ta}fZi2hu0–y•’ly’I¦†I¸Ö’7;L=»­€è‡K•<‚|9á§hä×Ûö”‘¶h¡wHÅʬ£ø˜|ƒM‚•Y·È~€³ado5†pD‚¬]™¬bÔÞ{×\ži…ÇgwJTo+Dd#WT+kpSysXcfEj{BIm"Xu)‚šYœšcË㌵ր¯Áx¦§gxtE“Sž“W¨yaŸ‰[žmĪzž“Z¸Ã}·‡h›jO¥rY»‹ÿÿÇÿÿáÿÿÑåÿ±ÍÈ‹Ÿ´f¬Åxo§Jb…C_„>~‹T³^y¬\h”RF@(“oS[v0jxH“¦~´yciZu[UzkMxuL~OjlJŸ´ƒÞþ¸¸äcxBxN˜m“—t¹ÊÄÿªš¼ilyF^Cmf=eZ8€{^„›SXy-Hr-Lj6¢›ùÿÐÐÿ±¿å„°Ë‘°â•‰¼wƒ…jž˜ŒŸÕ{„²~±ûƒÃl›×uÕuµVl¢W_ @V‡9oAg€Fp›Zƒ£n}¥^h™It©c§ú“Ãÿ“¢ÿunÓa ÍŒËÿŒ¢æ†Û—¡Ô‹ Ô}‡ÏlŒ±jq–j›·¢¾Ôœ¼lt“Le‹L`…DhˆAS‚=a…_½ŽšÊ‚‡¿ry¸bxPbz?Ca>aje“u¤Î¤ÒckžRx‘Ur…CPnFj‚Z‚‘]Š›k˜§av‹K]w@VrNrŠez™di†Gb€Qm—lƒ¬…žÇŠ¥Öˆ§×ˆ˜Ê‡–Ê‹‹ºsmŒMUyKg‹Sb€Ed‚br—]h|QopBYr4Gk7LuBSzSo†a|•[| k¥ešg|—go jw©v®lnžei‘O^…RZ{_^fc]ewWa€ShŒZy•NXtNj‰Xn`|ŠVsn;`V=_^E[hRatW]Kf~I]f>liLwtXˆ‚U•g5š;³Ÿg’©mq yjloy`vƒNs‰Ku‰Vf…XQ|LTc?ma3Hu3HZ;cZ4cd3^j=^pPTdGDk=MR4dU$Rn4\M?iL0hh:cwO‰nYÌuPÿ‘Yÿªxÿ­{ÿ«„Ý«p‹‡´d…ÿ_LÿÇÿÿØÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ×䨟Ñ;e·%/p"!+B }GgŒFvŒ_¡„KM¢k;`]fF*Aj3{\;W–>MjmDL,i?+’\3K«^LkbJa1\e;npFvtOd‡OJ‚GsR>‰f$€pH’vPò›Fÿô~ÿÿÍÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ™ÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿçÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ^|¸ºrQr®cŽfg¢Qq„N`Rfb>_lH¦q>n¤]|Š\{VM‘sŽwHoZQZzF5X4HJ*`U0R‚?RbEe])€”Fr™nl–rV’]Yq?lt2My«TÒmX¢Q@b5BN$”]$b‰`~jC\„_o]8š‡;ÈósaºTa>zApTv‹W_‹aZ{=ˆj/p¬bOmUTV,Äe8¡ÿ³…‰xf˜mRr>l1yrE`~O[f2Ó‰AÄ¿dŒkV_6r^1‡_?Á†DtÖ£~{L´£a£Ö‘solb_Hco:…‚N|–YcžJny;k‹F—}<‚®okˆMmR1L;K)d;h‰M^oBx]M{A$L(=/z¨ e®eìõyÞû…ÿö“¸ó™¢½lr¨ir‘]pBuvCsu”oN¶{c‚„P´{UÕ¥}·±w«€f‡T¼Œk¨sd¢ŽhkH’T¿¸¿­™ÍÒ© À†ÿÎãæÿ ÁÞÁóš¶Ýˆºó¢µà’Ên†²j¬Ä{ÊÖ’‘¨\am5[S0}‘=b’3]q;u¦O[v:SZ1kVAp}Ko~Cbw;žƒéÿ¶¬ñ~f’By{B^v-Gc6³´¦Äûª˜ÐsqµS¹Á|‚ Q•“Q‡¦Qo†Xt¶NUŽ1Bm2R]_Öγ·æ’«á•ªÍ ²s…ªb{ŒT˜Z‘¨}޼–®ÏŸ¼ö¡¼ï‰´u‡¶pµo—Äpm¼Ld§Nj—Pt’b‰ºy„¸gw¸n½ó®ÿÿîÿÿäÿÿÚýÿÈöÿµÐÿœÂýžÙÿ±Íó¨Íð¨Ïá¢Ïzƒ¦_tˆJgEgTy•i’»r‰±QcŠHk–Rp Zu”nŒ´“­ÓŠ”¢gp‡HMp;>p5GdFwuU|‡r˜µ|–»mÊuœÙdr©Ld|9Y{3[‡B`–D`‰Hm—Rf¢Yk“`¡cWožjv¥pl˜dt–ix•w~˜nhv[k}vs”cfHN‚Lr´]m¢h‡¨y¹m†«W_t;Pv;Su>JjF^tSnyUjIJR;9@;OjUY€ev•†µ‰²q{–bk„T`…[`ˆfq™hmŽ`f‚]q”gmšdv†IU\:C\?Ma?OcFff>fnBivYl—l{©g€¤U`yCOX6TJ<]\R†wNˆc?‘ŒH¨‹^•Šk|›xk~tusV|†O€ƒ[‰fzYerTaiHjk;[o%¢m'„š;bšixcR´^<ù{SÿŒlÿ±rÿ³‹ÿ¯˜ÿÿ¨™­Ë–”®‡uvÿbbÿŸgÿÿËÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ Ëð>d³%,U,OxPw|K`„^‚xQ{y=[hmlRwqE¨ŠH[Âp5sƒ?:-UTrq2³Y8wÎ{i”frTXhDlcP‡jEPŸSsPUq„8•Gÿµ[ÿÿªÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ«ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿs·ïML|€{7Ñ£U„²yqºdrWSšL[V?~e4‡™RRbUMBjj7qzH¶¡SW~oOW@NH*J]:j‹?]™VgnP—§EŒ¡YhŒYvoUe¤MPjT^i=†p8˜”\_¥mQ{Ewh/„”OzkM@’1r¼_u‚ZjRZ‡F@m=HR!|_3q™R…ŽQC¸|n^5§“DÝàŒÆÿÉ¢ú¦mׂSŠLVi7^l>ny5s¡Q¦°W•¹”£wç·‹ôÆzgmˆX}xG[sDdY0V}Alb/h‘Hˆ?k”chƒDx[9t{Ue‘Q„‰N|‰]³ˆG§êš¥b\U|u7‚‰Hd¯g€¡Mn—W_uK¸q7tÇy~‡D@S9a†9f”Gn€P]~IETIt5spI\a?~™MaƒKfk7|2Ì•\¸¬r£˜vŒ­d¹ÀcµpS|Api*bƒLxƒIh†@z}DwŽMz•I‰’H”¢q€Å£ŸR鱆ˆ†lq¢UŸ³PÊØŸ¯èŎΚxQwª[ž¤bÓߦÐêºú×¶Ãÿ˜ÃáŽßÿ»ÈÿÇÊîÜÿƤè‹Íú£vÚt‚’\x¢U¦½i«ßŒ›Že”uSl”M\c2Ž‚X˜YC±ƒ`µlîÿ³ÇÿÊwžP™Y›ºo®°g¦í­¬UŠCªW‘^†G”qLŒ{W“sU[ŠJmSAaWž–v¤qZ{h?Wc;Ro@Wd=S};CO)ZV2a^1Wi,—ƒl©È—©¼s‚¢V…ŒJŠVŸÃkõÿÌÜÿÂÃæ‘Àñ“˜ZŽeš²`—¯U’‚Yla:qzC~S«‰xΓwÿÿð¤Û„ÕÏ—È鞣²w‹ygž¯‡›É‹«Üž¹xHS3kGHk^Fmj:s‘Nˆžb¢¨u£±vˆ”Q’Šaœ`€h®ÃšÖÿÂéÿÍ®ÿž}gb…fYŽMxL¢·†·`˜¸] ¶^”Zv•JpŽP¶nžÍŽ‹Óƒw¼f•Э핉Ï}‹–u¨Ê޵_u³Sv YŒœch–Fržu Á‘Š«r…‹¬[X~F†g†¤q®¹‰¼ÑªÜð¦Âù‚Ÿâ{„¼oŽÆƒ´ô ÷ÿËÿÿÐÿÿêÿÿîÿÿÔÿÿºÔÿ™µß—¹Ñ”¦p~vˆ˜m§u‚±[w¦B\˜8O~>eˆbŽ©qs“Wm¡e{¢fz¦]b‹Zl’^|_sŠ^{˜w‚µheŽYQwCktWv–Zs•duˆ[…—u£ÎšÔmo°ECj/ZqKj”b~³o˜Åw¡¸j{š]n†Xg‡SyŽd|¤wr¤eoUX}KIh7FS3H^HiŠ`z´k{µmu¡svŸ‡«ÛšžÄz”µil~BXr@Tn6Fb9G_?Yf=Za<:Q"):)McKh{Zbƒy‚­””Àob‰MHuV[”Vc†b|ŽYj‘P`”d}²p»`xƒ;Db(-P&*Q'/M9YrOa‚SX‹lq¥‰Žµ…“©ck’F_|9LY;WTOppQpeFq‡C…yUs“e]˜ƒjyps|Z…}N‡‡X‹t]nmSplNhb;om@ef8YbDbc;‡f;¡‡Enš[9ŠiBHDhI#Žr0¨†Dµ§jÓ¨‚þš‚ÿ™xÿŸ€ã¦ˆõ˜“ÿ„ÿ¡’ÿ©†ÿ̸̱™Ž¤Üt‚ÿ£‰ÿÌÂÿÿôÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿæÿs“Î4U}!.H"! HMPQX:P];M_Hb8ˆw7x¢cމ\˜œMZ°‡CypmU2‚p.wzDv†T¡yK_·ƒW~rh1ƒ¨B“—Xa«b¢sTÿØ\ÿÿ¥ÿÿëÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¥ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÉÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÄ™Úÿ±…¢Ò†[³škDzWɆ›–]•¹yRš^yv@iRX€Yin?ˆgEž‘^V“{cZPHe:GH0S3€W‡šk”ÈoŽÑ}v¯mp¦To‰[d…TLcIVi4\‚B[=nzHG‚TQk/ZQ*_j6dfAÕŸ6cשhˆL„Kk±rRyRK^5lg4‰o6·‹k{Ý–k|j´‹KÚß•ØìÆàç¹§ûÅl¿‡{—KweI™rTu–q‰I t€“fâºqi¹´£z5ˆ~^rqGYvDaa/_i8s6`{N_v;jr9`ƒFaY4€ƒGT‚L‡[1s©to•KƒI¨‘Sµy|R”¦^¬p~‘Q[cIsxIü©IrÓž_‡@kn7{‘Sr”jgzGFzDBM)gA*Š…YSyLŽ<'–o”†V|vJ„“Hv„E‚q<¨žN‹ÎgÄÂh€¶wd|=dw2Y{Šu;–ŸRw—JšCyvF®W°}gOHv‰?°Žx³Ç°¿×¼Ú«™­ižÐ‰…¹iØÎ“𿤦f“¯z¤¹}Âô–¶ó¯õÿ£÷ÿߨɛâà§½þ£s¥_Ƽ{Ùþ§Èÿ·¨¬pŸ™[ÞïŸÃûÇåƒÇºmŸ²dŸŒS³žnÓ¼}–Æ„ˆ…P³®i®½~‹”\Ž˜_—ˆH¡ˆL”¥\ƒPdxE_~BQW0™“ek¬[[]<~bJsjCxbGpJ=eH4Wd:Ww9>S-@E'BA)ZJ,jT:gsHUç俽ÿ±ªÈ|äÕªåÿÇÇÚœ Ê€õõ°Ðÿ¢ª©`¨Ãm–ŒeˆN{ŒLŸ«{ŸÜ„n”M}POÿ”¡Áü™¨¹Ñç’ÿÐŒË҂¨ß“†¡b’­Xji2cU3\[=SS-x‡Iƒ•Ujx?`wGdxB~Ow‘S\©¦ŒÿíÓñÿÐßÿÛÍÿ­j¨FŽƒ\—·S’ªTw‘;j‹0[i1‚Z‰•[|Z†£r»ŽžÃƒ|ªr“»Œ Ïp«TaŠJ‰¯yµojŠXhqDmIz™i–Ô‹ºufI[yJc{AXs;RlAt€U[…PЬk•ÃxŸÓ~ŸÃn†®y Ñ¡ÿÿÉúÿ¡Ûÿžìÿºÿÿ×ÿÿàÿÿ·¼Ï_dh[€qlxtUhcMTb7KaDvWi‹Nz [f¦O[—P_‰PpŽQnŸp‹À~~‹Up~HbŒ;X‚NqVzŒr¥oc€NUY9RW]©ª|¤Ér|¬M_[mƒ]l~^rGH]+9_Ge—jŽ´†·Ëˆ¦Åo—Xi|OirRb~N[{Yg{Qj‹VbŒFU~8Bo5Fc@ThUb|Zkx[pˆfuª‘©Ó”‘®l}Y`r5DZ1>L(:I/Kb;Sa2KZ5K_,;N-IG$@n7T=+vb2EawO-Ê·\OŠ–‡K(~m@€†ZorHq?k|@šX4t‘a¤M†¨XS£Zcs6ØvFƒ›zF‘±d¨Ûnˆ½v”YabV}uEźnÈñÁ´å±Õ‰ŽÄeþºkq£‰qˆE`k@ƒyH‰Ul|E„’J\yXDb0^D%mj7®µ_oªn‚€Ip„EcN[‘@‚>}²_~Ÿ7–¢f`L‡x=¦}^qŠVWl.b|5–yB–™Wªž?±¥k³±{x o‹…WÑ«r½lf|=Ua6†KA±ªrÊèÁÁʪõÿõ©ÿã¶Êx´ß²m¯pgžNƒ«VÇ쓯ú¨Èó‹Òß°±ÓŽÔÔ‹ìÿ¼ ²]§ÅoªsI˜¯¢L–•fæ}Zèí¥¸ÊqÚ૪¥}| @±¸lˆ’^­FŸ„dž¯mnJWg1h[5”O“}MÕ¬rx¬^{WÄ®€”°h—_yySetGRN5u<=oC>a`GL?)_k9Of2ž½†¬Ì•´Ê‹™ºr‰©oš¯u‘²maq;ŠUÐæ ¤¶i—zV§xT‘ž^ª¤x´Ü§¨æ™«Â‰ÿ”ˆÍ³hªªvØ·•Š¿c©»ÝîŸûÿñᢡŘ³l‘Ÿh¶Öˆºä}}ÅX„¤Q|™FlDj‰>sNx¡KWt6kqBs‚E‘—W•©n˜¸t™ÈvÆÒ¢¥×vo‰@d„1]y3Hf+{ŠTi‡5_[Bq“N]ˆQo’aŒ¹ŠŸÏ‰„Àu€¤~š¿‹—Ë‹…Á€°Š¸Ä¢”Îui›DgŒRœ½²Ú–­ie™KOƒGR‚DXt>FT-O\:}…g}«]“a©aqŽVkwV‹tˆäð¢Ñ÷‚ÅìÐÿªÿÿÎÿÿ¾³²cRn0cŠT\™=OqHx—R^„`ƒMp_{ c| q ]m‚R~’g‹³Š»ur§MR‚Ma‘RUxAPik9:n:3X:@WKr–y™Â†™ÅœÏƒ}®ME_$3C$8N2TiCcr6K_6TQ7[e9UAGkCTfEZdWeoZer^u“‚žÈ†”¾i~¢Yl¦Ql¥MIp:CR;NYVkwŠÇ“—Çt}Š=D_Xt§Š¸×‹ÃÉ´‚‘ªm{sS^o\u‡^…m|ŸhŸ~I« Ov§qs…xƒl\²daw^uh…Blª]U`oCi„=sˆG{˜NlŠOhpM^qQe9Vp=`i8CwHBM*Š\+ß`ÚšœÅ¼¹€åÀr¹pJ{DK\2Uk1Vp5Ij4xW1§uCz¦}lF¸¬_Ρt˜o‡_y‰SSˆdhx9ai9\v;oMXš\P<¯Ñqy…xsL8}X@{Ÿar~G™|FPˆd_g/ß§D¬ãž˜‘m‡·io¤\…{DƒLx³d~KšŒV{’hh¾g¤´K…¨t»»ºð³Ùÿ¸»ÿÒ½ã⼓©f|ŒYNoAKb#:V'ZF^a/`E1idKT‚GjZ1£‘Zrªqq‡AŒ–V¡ai“j€VcsI†™*‹½]}¡\š€LΑ]t›t]†7v€C„“W—z5Ñ¥sŒ¡h–d™r¤¦™“©‡·º†…¨ldŒICs4`C*¤th­žvÿÿòñÿþµÿ¸Ão}±jlGŒ®NÅ·’¶ÙÆÀÒ«ˆÆpÐÈx°â—ññ‹€ÿt“F‰Oƒ‡O¤žb‡LŒ|L®zOŒ˜R‚FŒ8„A–Jžªihw6ŠT@¨°rjˆNhk8vm>uƒL– ]Ù~³„T˜ŽOÒ’jØá¼rr4„ K“£b‡mH…·R@n2Q6+Bi,>>"Yy9jz?¡VE`'bZ2†wD ˆtµva£RHu7tvJŒ•[]‚=_r0ˆ°Cv‘7Zm*[W0À“{üåÃÇÌšÚº’ÄꌪÝq¥ãq°ó}µáƒçОüÿ¬ ¼r¾´²À§¹Š†¸h›cQzlJÈ®v楂áȃ†‘K–|Qt|K–«vžÖ~ˆ®j¤ä‰ÅY}šSf—Aaˆ=r“U­â¦Îÿ·™Ýqg†I|ŽId‡3u‹JpŽJMk3^}Ae†Mp‘Zh”Hq‰^ª‹„™m^dOˆ‰žÏƒ»y€¬yyªoj WVq@cyNyz\†‚k„Œfy–mv›kv›krŠMLh1Yqh06[-=X8FYZ‹¤~•®{Š¥q³wœÃ†Àå•¶îjh­:K€/L6T„H^zDZd;SbJnw•Â—Ä‘Ž¼~€®hy¦Xk¡OK{6HmKk—pxµcx­WV=<_;Z}\y€¤Ã §ÙŸ©Ñwj–:D^.Oe=VpK`uAQg9TdBeŒWyšau•^cˆZjŽPUr9I^7B`UrŠt…¤l¬o„½mw£PQr1F]4JjLSˆlˆ¾£Ä{ˆ’DKnUp–uœsš—m‚—fo{@MN,CM=Xi`z•}™Á}•vSmX_|qgug†}SV¤T^t[x\BqfCr^L\iDZ[FoZ7†_>„~JŠŽXq}`fwV^lMmYMgA…DªYy³tp–}ˆ‘iÊ€XíRä™ÿ–ÿ¡xÿ³ÿ²šÿÆœÿÅ¡ÿʧÿå²ÿϧ¿¹—È„xˆk­`~ðYPÿ‡xÿ§´ÿùÔÿÿÿÿÿÿÿÿÿÿÿÿÎÕñYu¾5M‚HS%,"!)!M1,O 50)+<"-)"24/729 _: ‹x8r¥W‡~_g‘JV|wGtLNS*`N(xH.›i6¥œS£¤dµ¡aÿÎwÿÿžÿÿñÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÖÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÚÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿóÿÿìÞÚûÿïÿÿôÿÿÿÿÉ`ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÕÜÿÿ¯¾Í³¥qY§gMjMSKa\5™}.¡­O¯˜i]±xnsUeuWm_@lm?s~KŽ‘I§´]¡¹“v•x{dZŒe@‚tKumW]~UG^CL[-«‡2–®d^{t€Bu”GVˆLQpAQi6W5\ŒMMi3Ig5}o+BfPSh+rq5ƒ°NežFWsEjx:xƒJgƒZQyKPe2br/JtXT0xbF{‹Pf–c{m8”¬p}°i”‘N“¦gÁlq£\„N…ŽX”„F…fnvKjuBŽˆCÆaŽZl‡A„‹I‚¨T}ŒcªYP˜†^w?wsA‡£`Àº{´ò­«÷—Z‘SOM¾nÚÿ¶îÿ¯ê’„»f[“T‹wQ™½i¯Ð}ª°­Ì…³Ë~Ù÷¬êÿ±ÜÿĬ®v²¶~¸¡i±¤n÷Ó‹ÄÖ‘‹ŒU`€e^;gƒ@h]ƒ¯rƒ±gf‡\bxNWg@{¤ly¦ZKw4Bb;MVC[fB\qFlt^tŽKJ^2d‚Ci~>chH„‹[lQ¨œv¡Ò«™Á””¯s…ªd’µs´Çƒ¿Õ¦Çß©Äæxk¤`„¦qŽ»lˆ¯o˜«€®jp€VfzUh…LuzK‚†S{x@l„[y¡u¨Úœåk€§o–Ól‚¶RpˆJhnHw‰e¿s Óki¯i„«…•Ä‚‰¯nЍp¥½†·ÍŽ·Ä…©¶d„¸`~µcs½fx»Y]Ib–Qj d€¬hqŽYl|[qŠ`xš^t­ni–NQoLWqZn‰l{¢dY•akŒR]wLd„g~˜šªË¨«Ü–›Ðdq”KkƒDm‚bž[q‡KtƒPl‡RtŒZ†¡}’»ŽŸÄu‚˜Q\‡DLzCJhGYgGb~Z‚ h{¦d`•UcˆQkƒVlˆcy˜js–Z{˜c…´hn£ll—c{“dtŽSgz`£?7dYJ7ii5D„K#qZ)99$($"2&i19R)KF66b+%D155&H!*+E:€OŒ¤7ªhn•jwNdžkOwVZX?bS)‰Q/o<¬~Lÿ¡Vÿï‹ÿÿ¿ÿÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿâÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¼ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿßÕê͹ÿÉÎÈšÿê{ÿÿ¼ùÿÿÿ÷Õÿÿÿÿÿæÿÿÿÿÿÿáÿÿx‚çµqZE€uM;DXI3626PR)\Q/ig8~[N¢•T–Átz¦uayfuH™Y”P‹¦[ƒrt‘iSk[|b.foK~bJ]”QmfMmT4[qKsw0£ƒOvšmwV‚I’^jwW<^FGM$OP"Jq5cj,t†MŠ¡HXzYnvCDoFK[)ba)enA\€IQo9\Š6b|Bm{Fl˜Rq¡Uœ™WjÈ|zž]ƒIš°{V­ŒXt9OI>^6ŠO*Œ©IƒSŽn/k©vuŽEMŽVKe7Xi+my1ˆ¨]W¯kQ†Az†@†žM³¼bw±oy›GssLèqJ—àªwXEi?He$wg,°‹d¹æ¨…Òž¸­uÁÖ¾Íû´µÙ¡ƒ×}­go‡Si…H}”QŠvKxjTg54†6Fäj~ÿØæ¥ÿôzÓnƒªTd¡]bx=Q™­‚®r‹“Vq¬gVm6yu6|hFm…Cqu=Šs7|oVn€Nod6]K/‰h>™¯f¯ƒ^at^«Q;µ‰j«‘vš«iнyž½nÈЭ~Óªt¶il›RŠr_®œr·ó—‚¾t`;‘R¢~\°¸Ÿl˜lŒjF¨›rÇÖáÿ·µú’„´`¦•eÿ¿xìõ°”žjÁŽ]§­mÿÿƒÿÿèÿÿÿÿÿçØð‰¦ðxvŒ@cq7cb,ŽmVtœZk…>wˆBT⹕­Ñ‚¢¦b˜™h‰žcŽ}ËÄ|º®p¼­sœ»d¢•feHÁ´i¦ô€ªÁ€ŸË{Š–WŠbO—|RªÌ{„Î`ˆ«ao»Rh€:nBHr^MnqA“‚f§¨†¦‹XYZ(YA,a?0B5%J>'kt@ÁÊ‹÷ÿËÿÿßßÿ¸Âÿ¤•ÇkÜšµãˆ ¬g ²jŠ—g©Ü‰¥ß‡¹÷‹·ÝìÏ’­»y©§r¤ª|º½|‹‚XŸªw áƒšÆgŠšp–µosžA\„0[†0gBz“X³Äœ¿ñœŸÞvr¡=O{(Ht)q†X›Ãw“Ívr²LRk?M]?8O)HS'B]1dˆ[cTy‰a–bk–Yc‹PnŒqª¸†yšMb‹J\y9Lw2Ha/Ok3Uf>\m>ahC‰^•“NsvVx W|›U¤k Ö”š½~ §e‰[™ ‰³Ô°ÄŠ—–k•ž…³±y~—L^w?Qr;Vq>P{Dh¢[h¸`u¾lq»[[’AeAXŠQz¬u”ѯߤÐÿŠ»q¡³p—¼SIz27Q*EUN˜Œ·Ù™¸ÌŠšÅ“ŸÑ˜–ÁxxšTr•Vw—UvžUt£h„¬m‘ŸÅôÄÍû­ºï†„Ãrˆ¶o’™O[['@V7LzIXcn—ƒ£cUr59\6F^G]za}škwQMZ4HgNY’‡‰¿žË¦¯ÊŠœÄk{žOy‹`}›kr—Vq{Rs‡Wc‹_z—~š«ˆ¨»xЬgm•Mc„Uf†Lc‰Pf€RjZršw®x˜˜]rƒD;H<>ICP`W_k…¨t‘«m¦q‰šZs~Qj…R`€?Yi>izWj›m„°obŒU]xjUeTUpBWv;\tEfbI]8lhNbrLƒoK‰pCwwJgp\ZfNRn?Uo;^c>UzBd_@gX7{]=_>‡gG}sK‚nN£xRª˜QÁ¨jΦ†ÿŒ~û•nî¥}ÿ›~ÿ¥}ÿ´†ÿÖ¤ÿÝ­ÿü»ÿÿÏÿàÁÿûù³è“‰œkpelMLaK^‡JP€Y>yc@Š€CŒ˜b‹´mq®v? x0RN&/! 0#.B*P2AS3^Z4Ow9SmBKb1%]41.%O:œW®D{¦ve˜nssUa‚JVkWi`N[lAmf9µCÿËhÿÿªÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿéÿÿÿËÿÿáÿÿõÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿýÿõ¤ÿäŽÿÿâÿÿÿÿÿÿ{ÞÿæyUÿþjÿÿÿÚÿñÿáœÿÿÁÿÿÿÿÿÿÿÿ¥ÿÿÿÿÿÿ\€½gYscY7I8UƒX3k`56=A{D,Ž¡ClzVUeA…[1ƒCXƒdRH8ic:Ç\?”Ú–t£ks‹FaŽQXzH`rHxr7oTf‡QQzUMK2rW1bz@YqJ`[9ii4azO~= ˜Rz€fDs?H]1s^&Z“IzB_›cKtOqf3„ˆHAqPYP-xf+c‡NPpE^;Cj=Vj)‰v8\‰XG_Ffk4’cGŒ¡i}¢|“‘^V—y[sDƒx=0pfQGak;„~Nƒ—ck¡k¨½_oÈ…N«PIp4Il(Ÿv+O¬wVc,iv4mžH~zBǬT•å‹uÉx…qJ¥iRh³uM‰ABg*Na"l.~h•–qŠžyЫx~¶ˆ¯ÄdÁÈ—ù³l”fM‚C^V2Œ^“Q{`­ÏwdÅq´Ärcµ[br:Lo4p:ײ~Çÿ¨Í÷‚Å鈟·m«¤K¸ªSÍ¡e—PŸ“aÿ·ÿÿòÿÿßÿÿب–|ƒœVvŠQ¼^W›‘Zv€HˆwIŒša¤°s†“d­’j•£]…ŽM×®}ׯ›²÷®Å†Uò••}Z⭋ôp·¨ofv8lf?”–n´³sJd{;x†@Š—\¹Ù Àà—¤ãŒQ…A9<ZO*uŽM‘yMe‚QoR3V^-TK+mW8qz;„~M·Îuåã§ÿÿÝÿÿíÖÿ´åÿ¼¾ãœŒ·j¯’m°´jµ¹‚ÊÄŸÓð¥Ãû¤¨É€–ªo£Ñ‰Ó`{’Eq]D¨”v¨Ï‰›Æ†“¾ƒ‡‘Um}Iƒ™e„›[ef;Ue1`Š9gœN•Š]œ°r¢ºkj¦@n§@Ly/b’Cƒ·Y†·X†­d_š;9I+CN)MP.Se=\Gt•R^¦R€œgr°[i‹_•ª{¦h€ªb²_mŽE`r7CT)Ec4X‡J`“LQ|JeˆUv„OUv;g|Zu€Ux¤g…¹’Èz¦Xv|V|­nw±}®Ù‘•Ù~‰­u¯åz‘Æ_o®NQ“Oa—P`WŒ©’ºèªÓ™¢Î„‡Â]o–U†¯s¤ØŠÌ„°‹Ïé³­ÿoo“[„¢^¨]³UR~7D\_••„®½„¬Ï¢ºá¬ªÅˆw [e‹R]ŽO^‚Qr“i•àšº÷¼ÑôµÑ雿Ѕ‘°q†¥`f99U0`Ob\6kkMy†F[nKTn@^j4”z;žˆUq‰`LxDGb/En)gX'j‹Rn~URŽ[\o:yUD‚fMO5Ud-im7TH\s@XrDb|C]ŠDr„Aˆ˜VÄ·s|ÚfŠXCE?e%…c¸nbovŠ=p¬Q`o=œ™SÀÒ~«á«vÏœw›_‡LPžfCh,Xh&O{8œ~=Z³ŒTc.Q['vg.‰~L½¿q€¸˜•º_a®ccŽ[p=PeVmŒ^tžbn˜Zzšd‚Yc~KZjBTd19Y0IeCarRrŽdˆ¨V`w;MeF^†u}­ƒƒ¬ou”^u~Nfq?\n>RU]‚O`|BXqHo€SgGX~E]xJcM_y_^v`o‹\z‡KfvMr‚Mi\|’eŒ›Ll‡KdˆLd‚Ul~`fwHMpTVTJ]U5Nt6GrKZR5rj.f‚Gj‚`‰‚\‹¯e]©rU~k€e@‡—Dˆ´xx¢Œh’}cƒ`r€X~{P|zNptUzePy‚D„žd·‹cµ‡[n™pitÄS<ËyEå€hënÿ™yÿ¢wÿ»‡ÿÙ¢ÿó¾ÿÐÃÿ¹®ÿÁ›ÿ»¥ÿ¦ÿÛÀÿÉÂÿΩÿÄ®ÿ¢•ÿ–|ÿŒqÿ•„ÿÄÞ䙚äÅg«—Z{q_fGga;b9^zJwbLp‰;`uYJfHEbGqc;UšX,JV!jx-x|=£¤Yˆbq‡GYw7j…2n|AUÚ¦bs‘V…e;¬—l\±Ð„ÿí™ÿÿÓÿÿæþ÷À¿Èª’]^}eX­OH𻆯°{·èŸ­±œÓžœÀ‡a¤f¹¹k”õ–¡W¯­‰…¬qw«T~ŽHÅÃi̾‰¶Ò’¾WSj5nm7™sS‹S„…E~šH“ O³ÀršÀa¦„IˆˆR¨|L¥wS„W††]ZŽ¿tŒ~?®žl‚žWvL¢­nx„Jª€j²›u›ž}ŽrMŽª‚~>…kLØ{kŸ½x‰}J¯Žc»áœ©ÜˆµÞ‡‰Ñxo‰T©›€¦ºo¢­d›¬o«Ô‰§â˜³¿w‹‹H¢¢WÆ©i¿°q–ªfŒŒK¯ÔÍσ¯¾sž´^Ûø·äŒ‡¹n›x¹À›Ýñ¶·u¦¶±Ä“¢]žnT¨ˆX½±{¦fš…cŸbÊqeëƒnÑnÙ’rÊiŸ|R›uQhy>‚†Y”§t|¾c€¤[Çlªå€¤Ë‚±Ó|”Ãu¤É„”Êz¼rÈl„Åa}·Zp•Zl“GiM¬ÆµÔª¶†–Âqa•HTyBYmGeu?Rk:f„X’¥wĆÃs¸mƒ¥r’¹v¤Yf|Q…†fožYi…`³¡l†¬bu®\u¨\|§_´o‘Ê|¦`˜©s‡­Vu‡DnDXqHxqm¤£{Ÿ¸†¡Û„x·Qu“h·Ï‹àyÐanž[{ªl—ËžÏò¾Êï‹”Â\rœGa’Aa‚LŽ¿¼€½žéÿÛãÿ•‹¿\¥I_†E]{[ˆž{“±v²pX£UP†St°oˆÆt‚Ã~–ΡÅí¤·ã˜¦äš¸í˜À爳LJ©³s‰¹yŽÆ„†·†‡Á†ƒ·i]…GWtXr–mŠºŠ¡s‚–fwŽTx•J]vF[whv–e~©Kb};Jg>N|IW‰Q]Yb¬[c“Ha‚HU{Qqu7Q`/HlDOˆmu¥‹¨r}›_p•a”\l†[`ˆ[c‚M_vCOrLi„hŠ­m{°\nUu„RgVb{O_x?Ra8PkGZz\<V-Y~?b`Lad._XApc7}—C‰¢R†Ÿa]¦nFpZEV7nK-ao7 rMÿÌXÿÿ¬ÿÿêÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿýÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿãÇÿÿ¸ÿÿ÷ÐïÏšû˜½¶‹ÿ’Jÿÿ ªÿ¾ÿ­ªÿÑ€Þј”¹ÿ˜aÿÿ{›Ø¯¨µnxm…ehmLsuGFšd^R>km9wnPqdBiˆ[j@ŠŒLkPTlaf^8VEs€?t’M_‹KggG„ƒDÏwD¾–³ªB’Ë{™³w~§fvœiN{SneLŒ‘L\Šcgw?se9owKs}IcŽJe~Uv…C~wKn{MO_>Hj8_j.n‹@yŸRy½i‘¤]–¤u޲ij•b®¦S“Ÿx||SImS/V2+A>AVb%kk9bUS‡VUsKWr>Rh?Oc=Œ‹;‰­Ts™^i†^·†M{¼¤x¦e{ŽPw•R‡›[¤šY¨žz»ÔŠl¹“L€J„z%Q¤e‹†<|°e¡ªS«Áq»Ü §ã·¡Ûž»ÉŽ‰Ù¬y’hGxDcr,èÏW‘ÑžWvQ,U56CGN~x9eX°Lt¦dy¯T©ÆY”ëʯm´é¬U™nRm72P.V_*p€DcqMH\,]n,V7gw-ssOŽ‹L™œdoŸZt‚Cˆœd„L”ªZl“Jcu2tw@¢£j˜»nܨkÿÿ±ÿÿ¿ÿÿ´×ÿ¾‘Ú€ª¶^Ÿ½‹†•d«„h§­„j¹t¹oTÈèÅ×ñ½n™ƒœ¦U´Î“ÄvBk2¤O?ªó¡¤ê‚¼l…yQ§¬m_ŽDLR"`Z4h]Ds‹F’ioI¤{N¨­m³¨tÏè—ºÿº‹¿n¡†Qˆ‘S‚’L˜™M«ÊvÆ™k˜±ls‘F“KŒS£f“r`ˆg]ƒk—}Tžˆc¹Ìˆœ¾`°¯p§œ`_tJyiBïó®§ôƒˆƒIœ…i¡›h¦ˆa•¨eз|‡Æj˜µo°§p ­i¥˜Z¼£r˜—_wR³Ë‚•é‚”Äq…®`Fr/__2wJÕ›r´Øˆ}Ðo¢¾}¬Ô‰x™Na…>”«c­Í|¦_­Æt½Ó‡þÚªêê úȘ§Àr—[ÒŽuÿΓù×…»ŸcvGUz6V\1tnP«Å‚®Ù‹¬Í{ÆÓ’ªÍtË\†Ãi¸Ø™£Ìq¢Â€¤Õ€“Àl…±`všMbH…‰g”¾vy´U‡­u§×ƒ®©hžœgsXp~Mk\‹¨co”Z‹¯ttžlsˆWz{T|ˆ[¨¨t‚¢ShkL{’^uŸOu\Ä©~~À_tªVy¥cƒ¨q‰«h{¥Tk†V†§l—½p€ªTa‰Fn‘d…ʃ•ß„Ã埱÷„vÁfv¨q‡¶o—Ÿm†¶gxŒ`ˆ¥Š¨×¢¦¸mw˜JlžJuŸIh˜R‰Á~ŸUxŽk¥ÌÂõÿ­¢Ð]„©Yv¢YjŸOg‘iˆ¦¶Ü®Á䛪͎ŸÔˆÌ‰”ʈŽÄšµÖ¤±Ô–ª¿ž¦y®¢|±³Š²¿‚”°„²‘…¸‘ÍŽ½vxŸcsšn}±sÉk²V_zAZtZl“Ya†Ec…vΚŸÖ_Vx3IjIbŽbiˆh}Š€©»ŠªÁyˆµfvš@IP"6P3QmVo™{„¢|~›eolt t‡¢g†”cn‰SlŠM\}JUyVdŽe†bYetNgoMZlMTjCK`3=^=Q|Wo‘Uh}BRoEZgIQm]tŠ^ˆW”€Yqr;YoL\gN[_EDrFIaBFV4@^/OY6[`-RsFUeM;jAKK2hQ'nyA]~ajziŠ}Xx¦TfŠvJ}hFcQfM0q["ˆZ;—}E°|V“~_w{fŠk]«gDºˆM¶Œhºˆr†oè~aÿiÿ¤}þ¾šó½¥ÿªŽÿ¥‰ÿË¡ÿȵÿôÿ½´ÿÀ¢ÿâµÿéÌÿàÇÿß¾ÿɦÿœšÿ‹vå¡|ƒ“Uzf_L>om?eŽTHsLGG4EJ+XO-…V5€>xZ”WuTi‹Nbm^q`AÚ’Gÿçuÿÿ´ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿúÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿëÿÿõÿÿöÿÿÿïкºâ°€º„ÿŸq†°Z¨t¾Š@•£Ò‰]ž€cÿe“”OsŽX‚Rmfoc1h£bftNPk`vY6t…O…‰ZbžbˆjKRŠ[esAt=Wu;sqGƒ†Kz‡Vw|HvhG›}H¼½d¡±qs¥hj„VzxIaŒ\qfPV_GYgIpq.y‰EvlO…“Ycƒ^_…\C€En^8Tf:T\3Pc7Wt(•a.ÜÑk€£’f}hlmP±lCÝÃ…¤û¦Ýá–ÌÖžt¼£ZŸfT‰Ed˜:FxIWc2Hb9{^-m«lQ|^Lh6cb1nd3‚€A«ŠW£ì¥kÁ†hˆ\›Prˆ[|r:‚˜_fšX†ŠH¸±dZÉŸI_7ji'\ŠL^ˆ;lŒ?r‘>œFžQŒlŒ‘b§šS¬u…\ck¡§V‘¿lZ´`Ih11T*>Q#g2c Nrˆ1yšP€ªTŒ³\·¸g‹ò—‘ÍoÞ~R’PJU,Y{Nf7˜€JxÙq]ˆ5QA^X,ªmLŸ¦zp‹FŒƒ4w§Y^k:hg4[WáϰÝéÌØ¥—¯p‘’V”¥R¡“]¢˜a{Lv8¢’a¦¨x{M³yn„n[²{š˜aÄŸw]Ù‚oÕ´¡óÚ¤áÿ¦¥¨c}”OʸŒºÌ‹¤ÄqÜûœ¢Ý‚£áu•¼hÖÔ›¡ßxŒ¶_“¨k–W¢‰\°±l‘ÆqžÜƒ”Ò…¢ñ……¼fˆ¯a’Èiv§Ny¡S’•^ó«|¨×x­±x‡ Z„§SŸœu·¾Œ«´v°ÖŠÇá§àõºÎÿºÐÿ©Îÿ¯¤áv¦¦fÛå’ÆçÍô“´Ò|Ä­|y·Vaa8™So²R‹«XzÉGŒ‘V¸Ä—ÈÞ›©Ïz¥À‰’´cœ­o²³m“Gv @k§b¡½š­v{ a•Éu‘Àe¥³ˆÈÎŒj€Ms`MlrW’l´aj˜DkFenBŠZ†Š\¼«†äÜŸþÔ‹¾·gŒQŽNfŠMo„]³¨u}®]{›i‡¦w€¬g‘Çp„¸s˜´…«Î¤ºlw˜V—t½Å’¹éŸÊö«Çñ›§Í{y¤^j|BZrC}žY€»c»€¦Ä‚¹W{ªX}·^s­[«g•¹†´BZt@}šyÓ媠ÑcŒ§oš³iŠcˆŒo¡³©Ç„©Ìxƒ­fƒ¦uŒ´†¤·Œ£Ãz¢b~Vs’Ov•TŽ[ž\‚˜cy—dv¥|оŒ“ÁroŠXe{_bŒjlžt‹²rz£MZ|A[Š_v²hw¯n~º›±Ú¯²Ôre~3B\F\pIMd6CYF_ux£¸¾éŸ­Ægj‚??a?UhM]kX^iYvˆbv–ou¡wƒ°o† bmƒW^…UeŠi|§pm¢fcŒ[Z…XhˆUqƒRmŠQ^—TQ“R_ŽUqŒi„“i…‹Y|‘_~‹atŒf‹^¤zT”qMdx.ugLTdLRjJ=iD?[?LL0Fd3W];]c.@n=A\B@G/IE)UY(S\5WoFnmE‡‡Kk k]|wDcV5PAOI5VLvT.¦_0µoKª‚a‡”c‹}b»hLÙŠJØ’g¹žs±{¸ˆn܆hïŒlñtñ£ˆÿ±–ÿ®–ÿ¬‹ÿÛ²ÿí»ÿÊÈÿ¾²ÿ¼°ÿȵÿÁ·ÿʳÿÌÅõµ°ÿ‘‘ÿ‡{ÿ”rÆžz“ŠrŽˆTM fMXZNj.Oj4]l.gƒFcmCqc>tw@ž†O—>ÀÈ’ÿÄÿÿ­ÿÿöÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿùÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿàÿÿòÿÿÿÿÿÿÿÿúÿØÉÖÿ½™é¤‡¹{a^“‰Vgƒ:xk9Mo7RX3mkDO‰@]h>RzCWU0\w0Na33R:8@pBt~Eožoct[fh8lf8^wMq~I—¡Rq±eY™rOqEdX*G`D6F7YC&Qw/]y9›6_š_VLeG2pY=„m<^…agpLKnTXg.zp-‡ŽM•¬CŽ `¤¡jÕ{ò¦b³”]‘URj1Qz6D|.²l'dß{olWozG¤ŠOÿï~ÿÿÂÿÿÿáë×ÂÁ¸—¢“xŠjiyP[|DMd>?Z+OR&Zv6”u;g“OYF[;c\-\bgi3j’@~Cv¶Z`ŠKfˆDXu;jt)uEy±nÞžX{»|Kt;7S3BT#\j,ŒŸJ`§[k§5s–Fˆ¬N]ˆP™;ªÈs¾ÁpŒã‰¢Pc WiƒAg›QE€´‚DÆÿ™ºÜš»íŸÎp±¨iž¹ª¶†™À’¨µmµÅ~„Ÿg·€`ƾ”³·af\O{4h}8D‰Ai@NT,gf5lw4Ov„…L‚¥\p¤F„«Px>k…6î{¾Ë’Zq›Pu}L†L|•]¶¼‚²×‰ÓëÀâÿÛÈÿÁ¿õ´¬ÛˆÇó—É⋯Ö|ͽqÁ¬p§žj¼Ä‹„Ó\i„E{xH“›q™Þld”;mgQ£qŒ´b’­[‰¨a’®mž¨]}¤F‡ª`›ºŠª¸„›’av—Pwg˜Èwo¦_•œefx=[U9peKo‰Y‚ª^x–R‹—WŽ¡W”•^©›d•]™¥x¾Ä„­©h„œU~¡X°š_¯‘cŒ£Xz Z^ˆ¤h}¸o™Ì‡žÒˆ¾}‰°kˆ´it›MVx:TzGŽ‘yÉÕ®Íÿ“ŠÀarœUL4/D!YM(Mk,=a9Qa2AX19S8:B(LF#DT'IX7T_2sa0p{8Rƒ[ZdfbSD_f@IxGX\;T[1‚V5†t=‘oYŽƒP–z^¶dZåVñ’gí£{ڣɩ‹µªºŽuÒgÿ™bÿ­„ÿáÿ²–ÿ¼›ÿÁ ÿ°³ÿ°žÿÀ¬ÿ¼±ÿ³«ÿ©žÿ®œÿ§¢Ô£•üЉÿƒuÿœ{ÿ£}º£…`–~‡~S¯Ie¨_nwHršer^y‡Ufq=­IÿÄ[ÿÿ™ÿÿîÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÕÆÿä¨ÿÿÌÿÿÿÿÿÿÿÿÿÿÿÿÿå´ÿø¬éÿäÒËÈ«l¤pkƒGRŽNSo3Zn0hu7uŠEgŸRW‡J7|JDL2_d*ZANˆBF=Qw7€eTl2u‚9ŒžT’µ[rŠ`ƒLwŒ_`|DZƒ=ksAZuIJoIZ\)wc+tqBw‚T‹rVŒQeƒQjˆ=s L†U€–VЇOš¡dÃ×xŒè¡_“m¤ˆBÔÞ…©¢rq‚i”ƒTOyVrS0qA[š[8YBDOCg`x+Ec=da3¤FFÅž`d8k{<ŠCecHFpA@U)Vf/Gl7Mk3]{1eo=jd=]‡Ua‘DuI¡´~[µ†dmgžMg˜Io—=b™Bw‘F·n] k}_+ÿ®l©Ñ“u¡XX:eY/€Rq\W”M5^1RW!`7tŒH˜®i¸wzwDR†9]f0–N±²qÜ×…Øÿ•ÿÿÊÿÿëöÿ߯çžÞù ¤ßçâ„ÔØ•ºùŸ±æÉñ¡É÷™ž¬j€‹Ngz@wƒG§“h¶¨s¥»pŸiyhGxOnC^f6Sp1X_4—oK†›Ymi<‡¼Xj{0jf4¼zÄÍŒ£Ó|¬¼|–œ[¼“oŒtSð¶wÿ{ÄÀÇÕ›ä÷ÉåþÌÀû¶Ôߦ¡ïªoOrƒ@€NtƒD™ˆU¡}P¯i††`~t[ÿœˆÿðDzŊ¡ÜqÉ»‰ë³³¦zrUjs@]v>ƒqT¢ªr—ZµkTÀo²Êr–Æj†³dœÐ{’Âr~™[¤°j×¶z‰¬VŒ›WtnNg|JfrExeDk•Kb‚?Zm2}|H`~:o|>½´Ó»q¤Ì|€•bx®YeL‹»k¹Æ…Äj¬»ÒåºÀ±¥ÁÁ™¨¨oŸ­nÄ\’­NŸ¡`¿£l‰Lw`œƒ_v—Kan5xtQ Æmž˜]å—t»»^£©`ůwˆ·\zŠTy•Ew™LoZ>cbA}wU…Šfr­ZV‚@œnœ—_¢‘[…‘OƒwE~eK‡U´¤mˆ‘Z’’eƒšZ›l–£g|vNuxR“g‘¢Wf„H‚’Z‰˜S~’O‡¨^x¥Qs­U}±fª¯~´ËˆªÆ‡¨Ãx‘Ào{©UŽ›V{³Rf¥T|¬[hªqǾŒ—´[`Ya—@/d+/^2)U)5Z5QƒY®v¸r~š\n„Uužg‹Ð”«ç€yŸCgJm•fœ»y…£Qk—R„¡cާe«eˆ¦g“¿n€¹fyª`s²e~¶h~£^‚¥{•Êux²Y«hŸÝ„£á{•Òu†¼htVj†NPtG`ŽZe£W^—DNyDZ~O`ŠYu“Pp„O^vG]€\o’`jej¢kzžUNs3=W/<\*=U5IfKn‡s’·§·Ú›”Äq~šYj…SeUeF]Zgžjv£kmjšuФMZj7TnZ~¢šÀ‰«É†±¾r…—\o˜sƒ­}ƒ¤q{”grhn‰RVpMlrU’ŒrœŸe€F^SIg|at™cXX7dX8]X7@qH6ND=O3PE%Qh)Um=?qM4P87<*8F%IH$SS)L]5:_8GR.H<\@2bK;rU8fdCSxHU^FUnB„lJsŒC\{[y]DŒ}:ÆfLð™Nÿ©wþ¸„ï´Žù¦¿´’±œ¾zoÂŽf÷}pýŽrþ£ó¥ˆé¡Žÿ‚ÿ›{ÿ°—ÿÇÀÿ²ºÿ³¬ÿ¶£î±¨Ûž›Í—‘ôŽÿŽ~ÿ¦ƒÿ³ÿ«†Æ°…ºt–tœ{[•­_Š«w³®uÿ¾oÿÿ’ÿÿÙÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÞÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÎÿþô¸‘ÎÆšåÄ~À€_¨„BoCYN1Vr,Oz;Kg+YT+el<^†IhdFTƒRbw7ZpGQs=BZAY@*pR/eˆ]ˆWiª^x™uqv9hwEeg@¸e4Ó™X†Å¢´•Qe¢D¡‘iŸn€³qŸf™¨fĺ[§—zw­q—UJppA`tNLj?:h.YDqh+xsCÊ•WƒŽltPŠŒOë~DßÎt·¹‘¤£o«s¸—Z|€œ{a¶·wÊÞ•Ú¯ užrR±Œ^z{Rze9„ŠL†£[S†hªw=„áyVuCQ‚2>V,75$W!®¿|Vœ‹}^=`MW~DK{1_M9D?A;'UG"ga(Hn99[B9Q6.K&44C.6E!E),G7)PS2wN3oq7€vZcŽPohM~}Go€L•jK¹{Bÿnÿ»ÿ¯“ö³’Ϋ…®¶“ª‘‡›ŠkªxiÌs]ãza݆j÷Š|ÿ›ÿ§ˆÿ¹˜ÿª¢ÿ§ ÿ°«ÿ³¥ÿÛ­ÿëÌüÚºð¸µê ÿ£˜ÿ¥›ÿ¹™ÿÔâч¡x}PÄVÿÙ{ÿÿ§ÿÿÔÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÕÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿ×Ӕ̪pž}—’at¯gfiPC|`?O9KU#Th-Rh$Qx9Qi+w2?šIU\G^r1\p3Dm=RY05]4@;&H?oF%w}JŒ¥\h»ggŠaRm3v]1£sLìƒLz²Ka–hÄ8 £`n|wˆj7sš\“zL¿žSã¡”¾~akd}V,ts=I‡OQ]:cV.ul7©[º¦s£Šn…ŒRl˜fqY<±dGfÔ~ƒ†TgŸRcnMd“Fp„R}–I²Q°“w\Ú»}~M›TK^MbC)xw9YˆUYcA–‡>f¼cA{M]O?pH:C*µ FMžžqŠM„š\zmOZ”Tl;u²`Vœ]eŠEP‰MgwB[>gx?JuHV>*E];†X$i”fqkG[YY{.Ni'^m/\„3Jo3V„2U„!qNki=zuW¥h]x4`j?Ùpt›Æw{ŒWH­E”Ÿ^—šZª^‰¯_qªa~ªg„ªd‡³XžÃmˆ¹]°°k¦¶p©½Z„žLuF\ˆ>|šIy¢Ua¡>uŒG›ªh¸Äo§¿s­Ï~†Ç`t¬_…Šdm‘RvzAqžQ}˜S€]V‹gªÓ}±Ù‰øí’ÙÙšºáur¡Q§j“¯W†{P¡¥w Ç¨Ì‡¡ÂnµÎ{¶À]‹‚HŒ‹T”[|ŸUv£U|«i”Ÿj}¯VmŠAx–PuŸY‹\”—\}›Xi…Ss‘_•²uŠ™d]dILUJxx`d’MV|Ac‡Ml¡NR{9QWNnˆp›®Œ»Õ¢ÀçšÅlgšPa‰V{™~¨Ô|tIZ…W{²y~½ga—Ia‰R²~‹Æx‡·j•Àjy¢Le‡R{žv™²s޳f}¬€•Åޱj‚©Pa8[ˆZ‰bnqTedFWd?g‡m‘¡±äªÁﱨÏvyŒU]qD\a6O\AavLp‰RdŒeo£s~­luŸ[eLdx^€›on­Z\‚G[w;GS9KW^y‘«¿~œ¾dc„;S^8R^8NTBPcM[pDTfAWkGV=N`=Pl[f”•h‡¤t˜´pŒ¾uχ¾}ŒžZd…Vo|W{‡\wˆ\‘ˆ[x‘i~¦’´“±n~žs«@L-WF+I]17Q;4G9?B'ZQ"Ve';m=9LF8F+EH-v^/j‡:EŒS?gD8[00L"?6WJ;u+:N;A5*FO(V?!bE#fk?PzJ^A›€/“›RƒyX–{NÈVß—fó…zÿšzﰃᶗ㦎Ѫ€Å›ƒŸ‹wpi¯c_ÒpTò†fÿ˜|ÿ †ÿ”—ÿšˆÿ ÿ¦˜ÿÄ¡ÿøÅÿ÷ÜÿçÃÿ̶ÿ¼®ÿ½ŸÿÁ¨ÿ³¤ÿÒ¤ÿæ­ÿ÷­ÿÿ¾ÿÿãÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿúÏÿÿðÿÿÿÿÿøÿìâßàÇý¼¡i–ˆxpq…F<ŠXUI>Na7>uPF^&:S"HKU["qt6}’?jª`lKW—`Di6\1]oOw–\„³u­Ó’”ÇyxžZn‘Or•h¦Ë†¢Qt~X¤¥¦ÌÞ˜–Ä`kŽOhŒW|˜d…ž]~‘`†¥i{±dmž^}ªpÀt„ªeƒŸSo‹@dŠIdŒ>Rt9Be-6R&:T*I^Ed„r­˜®Ó·¶Ñ™ª\f~Hq”Sn“KjŒYg‡JUpRg•p‰¯}ƒ´qy¤V`yJur™Äš±Õz¡KWa/3J;J}XtŸt˜·„œÂn€ªY^ƒBLi;@d1=c:C^|bBœgRµwYõ{Uø•bÿ¹þ¸ÿ³Ç³ˆ­Ž‰šxr™t^ªkUËr]Ú~bÙŒuÚ“€Þ‰€ÿsÿ‘{ÿ³ÿȲÿïÌÿëÉÿïÆÿóÒÿѾüлÿ§¯ÿ»–ÿÿÁÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿëÿÿõ–ÿçÏÿúĽ°\_mlTBŽuDL˜giqC:zJHL-mZ-FƒH@mJ8Z.DQ&Kg(]j*Ž|2^¢]}…UY•OUzFNr6Wo4[i5Dv2‘R1Šƒ>n{e ;†g}^h¼jŸ–HÉ­W{Ÿƒ£ŠV~¬j‚‹fŒv=t©ginLh‹HkyJIoG^f0•x:º”h—›u–š^h—^m…C†„K§‹Iœfö‹dy®‹ˆ^“¾eyƒ|hd6D:8kO)Æ›J»Ú ˆßª“Ÿgx½ey™beœM²dMŸ¥o¾q}¯ƒoŠtkhE‡m>m®ke[KJpJ+`5x7R£\¤˜JKy{P1`O/sˆGa‚Hk`4J\1_\&_O0F[,AU$UW$\v2RT8fvDcŒBeœQ^k5Z†C^}Lx…Rk›MU…@Cd6Rg.ttEvPx­r °i“Æx—¼m}£mg¡jUIf€9z³\kœW„}F‹—clˆNg‰;]Fu‹@€€E‘¢L«¸o¥Æ’w´g” c…£q¹¢gy­iR¤W_X*dpBx…8A `!.R&vXÁËÝï­¼ÿº§Æˆ«¾†Íã™æÿµÑÿ³®nž…J™£JÉ×{ØxoŠ?Yk3_d4~b=xqH›oR‡†^¡aŠ©n„Kµ’ÊÔ¬©Ô”ßÕ±ôÿÙáÿêΉƒÔqj™ZFi.º”k—à}€¶^“­[骅‘ºs·•bÍ}do>fžODb/gw:u}ItƒX{XŽ•h™Ê¬»u¢¤f•›^–˜NŽ·d›Çi³cŸ±pš†N³¯nžÏyv•J\‚1c…/~šIzµT“ bɽ±ç™¹Ê}´Ä˜ºm¡Äv”¢_Žªa’£k˜m³¨|›¬c˜ŸQ~šE…iEÜÍ—’Uz“H”Dœ¶[§³Š“Å‹£nq—Y{‹Q—‚H~tDjh:l`>‰ªN±Vq©Knp=q™Hj¢?}˜MœÉz¦ìŠ“ÒŽ±ã²èƒ\r:v…Uv£V[j:|cSt–NsŠGŒQªÇ‰¦Ö„¡º«àžáÿ¶Óݺ…¼Õt¶ÂˆÓÿœ•Ýi|Pu‰=o;z|NkwJot8o†A ´l³¾eŒ¢Y„ŸV„¸oÇv—ÎwšØev£Hj–RnŠO|•S•W•UzšU¤X}®x–´˜²l¦ºi›Èsޤk€¦V{¯`ƒ¯XW~2..'giQp¤`wŸPx—S_KdxQ‘²˜¿p•Rn‰EetU¡¹€Ž­NvŠP‚¦kuƒPei=Vh4Zx;_Hp†U†¡fˆÀxÁs…·Zp™Xl]}¥]‡±Tl—9Vu4Xj@\}AW|K[Gc|IT~^v«q„Âޏv‰œWbfBUbDn‡S¦_~¨ho›XZƒMc‘izšn¤`mOi™R{–s¢¹°Ñtp„;B`?bžu‰ÌНp…ªy‰´x¯dt€[x“ow±^_˜O_”Wkš_nKJzGSs_v—ˆ’©a€}JtiDajMws–¯tžj€¤…¼£¿Ì¢³Ãˆ¡²k•\v„rœ€–¥pt•hk¡po¦nKN*FV08]4KL1PX)NW:>^7BU;YT,yc+}z<Š]o”`\Šu:Š~>?S5Q/69"V=qP*Us9>~VF?FW<&Tb)lh3…{C±ŒImÄbS—{jcL{n3es@xUCmjŽsGF’nVQ#;I-„V wƒD8]4KGGq!&FIC[X#”n5}®q‰…VyË…Sžcf|7k”ANx9W}8h‰Fz \¬e“pxŠdo‚P_YFP^9u~H}™cw«[jžLYŠZ‹I^š]mRt’`€¬oƒÅw”Çnz³Wc–L_‹OsŽ\‹º[kŒUC+;m5'E,4*]=Gs/2cG[}6§pF¡j?¯bRƒ‘Xk[lxPr’H€‚V™†G´ÖniⓆV¢¨glÀdˆV|}<ŽˆIdœ^rfJhdAWvCaxAŠ‘Hšš[t§xmVlzPLkNbo7Šy>|’b{Y§bC|¤l„«`rµdm¡]k˜C’{M™[mvb‹o7Œªbs€cl^8˜[7•’l¢i…Ù¨Tne/T0;0MS¥‰>·˜xr wG•YO^)Bg@uk2§Êk§wv‚È‹>eY@G!?L'x_,I¡lFX9jM)N{DJ^,Zg2L](pQ5_8‘v@qn@fP,wnN‘zTSZ9vŠG¥Ãvsà€qY7}gF•kPÿƒxÿðÿ¡ÿÇ… [¶·aá±yiet…C}–R{ŸS˜™g‰‰[q€Pc˜e‘ž¬°y¤šh€vN§fV¶„d§|asrJZg3jf8žxW‹€K’Ob„H•­€¯Þ”áöÇÀÿ½æƒ—«Y‹Y€œY̽š®Ñ¬Óˆ±`˜­^€¦Ir¢I~¬So©F‡·W‰«Z„qZ²ü‚‰ß[ƒab«\l…|©àŸ}¯\a•Gr¦Vm“Qy mŸÑ˜ Ëŵ‚§Mmh5x}C‡œ[“«v¹`s¢I\‘M‰¦‰¨Ò£Ì{ÃXŠYÒÔ¡¨änŠœf¯µu·f Ltw8Om4YŠGi‚@tiA…}X£¤‚§ˆª½·Îúû뢪֓†­gs”G„¤e™Ç{¸Œ¯¾Œ©®€¢¨zŠOp_=Pf4L^?drN€™yѶœÂΓ˜Ðˆ—ºm„¢\{Ol’]ޱ€–Ênq’[u[lzNwa¯{¯¸‚™’Zt‚_••u™¦o‡£d…X~™\|Ÿ\v¦a†®Ns“Cd–]{¢OX‚ASv>IcCkŽpžÂy‹©lŒ¥pu‘EBW7KeZw—lv™]e€MayRq˜rˆ®ex”c‚’d…“^uŸn…´m‚¦^|•S‚—Hm}Iu¥[‚¡Uz†NmM_zTg…Yh†IMk46>Vvw‡Ê»–Öˇ¥°zj˜h}ht†at‚­²}›“MhgIptW€{[|‡d“‘‹¶»¸÷åÑÿîÅðÝœÅË’¾º‚Ÿ£~…¨‚~™ƒš…¡z|›hIH:AG-=H0JG0LB$CL)3C-C@1PK';R'QQ5\b-lpMwwa[k[‡z‰m]—HŽ™q™¬u¿‚vž~TshJQ>YV0…m4Ž€Fb¢_skdk^Ayj_©eBg–Le\[]XAb@€“O|¢^m˜_n[Ë]KÔjMÙ‡n°Œpç†ò›dª˜‰¥ƒz²Ž_œ«{´z÷wbÿ‡jÿ›„ÿ¤‹ÿʽÆÅ¹ˆš°{ÿ‚ˆÿˆ{ÿ¿§ÿñ¸ÿÿÿÿÿÿÿÿÿÿÿÿÿþ÷ÿÑðÿÖÖÿÿàÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÉÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷¶ÿÑÿ«Âÿ߃ÿÿÀÿÿäÿÖªöÙ¸¥¹µ¸e–|Li_ZX4Pa-GwED`6,b/!F*.3WB:s4@K:6]9?L*SR,hs03ˆG>>2DT(<=+nJ&MŽEOsDhs9>zC=V8GX!V\0bn9Md?jb5g†=om<“s>–M¡†\zŸ_n¦Ms]¸u/¥Ækk±‚a†W¢yKp˜NY‹bdq6lm2\jC\rAOW>_a+’z3Ž¡^Í£n¦‚^vzg]iOWj9V_'Yj-SsA”…?}™Qoªfj—V|ŸUa¯eU‚I]{8Lu>Wu9c~H±yE[ÕŒCN<‘G*®“S®Ê“¾K€f/H-=:Še-µtž­tzihg@]‰OŽ›O¦ï‹^…xq^Dx°jR’pLL3<>"K<“a6T´‘\n6Fh7]o-@]977&I?uO(“¡a}”]I[Bi,Œz.SsXDO+OL…„7ʽlÃ{©~HnLvS&y†UWvI\l3jx7SwObL/o@s?‘T,#S9(6B<zz3n©d‚ŽH¶ËzÿœW•G_m0P]-Rl+Gl7~[&ƒ£kw¡Sp…HLT;\T+ΉQÛö¶òä©kú«2k1F.¢T8s¾Vt9|ŒF™Å|q¥]V‰CQN-Ho+Àu>“¬z²†C¥É€‚·G§µL–¤qeM5nc;¯½f—ÿRÄa_x@`ÂZdc2rb<’T®Ï€¢ d˜x_«}VÌ¥wÅÐ×Û¤ÖóºÖÛ¨ÈûÇèÿÕ«ÿ½¨¾}¢›YÒŒZ›€f£·f³aZ‚IYR(tB˜¸j†¹_c”NGg6‘rUÃϲ¾åÀY‹UBF%Y_4XKšvT —tš‡eÝ l­ª†¦¡^±»u©Û€”¯^`Š<{‚?g›C\}8ŒUq²Vtz>Ó™q¥›nƒµn†½|…´{f•U–¤q§len=dX7lQ3|[6n7´nH׉_œfI©mFxŒI‹QtV˜§yÅÔ¨ËாΦµq¥W€…Vu”Tˆ—i™ª~ˆµk‚§U±¬dž›T{ T¼¹ƒÂá’”Íl_„>JE+†yY² i±Ç‚†Ãq‰Å„—³u€ZÊeg˜E~Lw‹Y¡ q‡§VRm(BI"S[/p…@•“UrŒKo†Kˆ¤aФc†¦d†¦UqoM¢Šoмl’ÁtªÅ|…±\ƒi—˜xŽ cp†E^ƒAu¤Vf™FqtAnjGm’fާ}¦È¥©Ý›¶Ô¦·Ý“•Â€Ž¹mtµnŒ©Šœ«š·‹›°ˆ£§|¤£fš’Xu@Wr5Gk2Oi3?^+__[Š•p’¦n¥ºry˜^‰bœª€©Ìlz L…xG|sKu†a§k‡ŽVuy=duBv‡S€’[˜Of‚Mo‹^|£c|£[{›Pm”KtšZƒ§Tm‰Ca‹Jožm¡¶‚š§_f`‚¬j‚¡Z|²Zo M\xO]uFZh<^x`ƒ°s–¬f€‡[…‹Zn‹[hŽbthv¢TdžKY…F]\¤T`‚9Mj/Pk6TrBTzSk’Wjy/;A1JePfi…–~Ÿ™qÇŽoŸŒ^‚Q\lfŽŸxŸTasVgxYktYl{dyŽ|¥¥œÂ¹©Í¶›Äµ“¬Äž¥¸œªÅ”¨¶y|Ÿy}“‚—Œ•hPO@@E*A?'KJ&FD&;H08D5B8&LN%XS,wg7xˆBrˆ_mzbru^e‡e„mar{Lžo_œ–][º„6‹”ENLZJ!sf6~€G§uNbœ[`loYd>t^DœsfK0@{,KWEQ\(5q54Q*SJ$F_)Je2Ki6de4e]6‚‹Pª¸T‰ªbz—\kZ}‡AVžeŠ~AV•?VxÎs7‹ÊZ~V6cI>G `d*ŠˆEz¦rWœnek9KqAEH0VN'Nf?p4±°k~ †dšPIu6‚a(V…Ohm/„¯Tw‹^[=]ŽUoo.Gl<|\%MkHKp)Qw.Pi+E~=c[6MwAOh8ƒ_<¹´pV‡^PP(tk4«ÏkzÅo‘³g“ÀkyÃeQ}DDv*:a"Bb#4OERsH"‰¬nBœO:N$AF%§]7‹¶t¦š`Z•jEP-)X&T7 xO|©i{–@§\QˆE\w3˜•LhÖxEl1g€4w“H}=–@™Ñ_]k;Q]*h‹3ŸªE²Àr¸Òyÿ×~ÿÿÿúÿÿÿŒ¬ÜvºêŸ|°fŠ›Oq¡Quv5¯P@¡lX©|s¬”s»˜}äÀ‡ÚÉ¡Ÿf~vFwu?ªvI¥¢iq°__F,[?)|ƒFÇ‘|™Ò‹‰áqMZ0^N;ޤq…œfwsQpudXl<€R:{fQ‹WŸ‘j’´yŒ _¸£h˜¿n¨Éx‡±acŠDn}?{PeZxV [¨¦d¯²aŒ¤d£Å‰Æ“¸{ƒ‘U’Ž^{™Sk<“‹T¯]¡ŠRtdDplAfŒFZdH/ ^<#FH(HF/[K,RL0gM/‚e7«b;ŒƒBkdL€k>WUPF@IX0>cDQP9om=“Fr™cAª„XUZ„S$h’CexZ|tI_tAieOpfD€Ox}DwuKxxD€]>ŒiE†{KjŠTmtYdoKkiE~tB|ŒXžuZÑ}OÐ{OË‘xÐp»‘xÖ–p¾¡zª—‡˜§~}e¨aRägRïx]ÿynÿ…gÿ¨Žÿ®Œö¼¡ÿ±šÿˆÿ¤|ÿ„ÿâ™ÿÿºÿÿºÿÿ×ÿÿÿÿÿÿÿÿÿÿÿÿÿÿôÿÿÿÿÿÿÿÿÿÿÿÿ¢Ê¨™¤ªÿ“|ÿ»pÿè¦ÿ׬úÿ¸ÿï«ÿÔ…—¬§r–V€d9[P‡C7}¢ORª}%vk/0>!a\GH\zCU<1[9YD$Na9JE;I>4FP9SO4Kk5nW(rŒXSuM7V@]F,6M(dk.t‘Jm“TÓ×uˆË¯IŒe?\5Š_,©­joŽbpžUjšYEOIg/'ªF-†‡bnŠ`ko?n.y^+jw@}Ž?WœaYK0`]36e-AX"HL xd1Ji>Lq)Rf)~g-Íu¤³jšq}šc}´m~•Zpœhz™`Ÿ¶d³·ok©rbv7´°SX¿w[z@N|/Iu*Xw&OŒ9\9cz8œ‡Hh·d]g7gY:sZ;^kHdv=fKk…Fd‡E\“K†—Eš¬gf‡AjŽAg8v}=Y‚ŽSt–E{±Xƒ·[hŸXƒk=­Õ‹–Âo~ª]’V¬¾vÁÿžÇà‡‘»qʯTÿ¹³÷ÿþÉú£¡ß•°¸qËø¢­ÿ³X‚P8; 8)6/46ƒ\1åŸx±°q‡¿lg{>wjHU[9Q9#hd6Tm?ƒ¡Wœ¹p^BwY7°Ætqù}MB+”œkpwOdRGKtBmbU‡Œa¸iw|VŸtX¢£uœ´i‹”bš®vÀir©Rˆ~LpƒFu”IvœSo…I~X‹ˆN˜œ\½ã¦Ö÷ʞ锑¼i‹[q†JŠT„F§·Êõ¬íÿŹÿ¥ŸÏŒà୴ч©¸n”¾Z«K²yX¡³fŒmPs_Q„ENn=É™wªÓ€™Èt…Èm_Š9q‘Ce‰4p…K\6My\Ô”Îÿ·Ùÿ³Âþy’LSZ0Z[DsyS€ˆZŠWŽVy]ޏ«fu†^ƒ‚Y‰`†´h‹Ÿh–µ‚˜Í„–ˇ›Âƒ„£m¥tˆºmm•ON_;kyr´Å£Î蚀¶bz›p£¹w‘¥mz‹MjgQ…~Zz”e‰˜RZ_/E\Dr†\‡œdŠ®t¾v‰Ân·dt¦Ov”Orr?XhCl„?`ŠHt“Tz’^™°sžÑx ÑŠºVg~Hs{Qs„OcvHclDpˆ]’®q›¬g€”d†¤h€\xˆPhxBZa9aZ?eeRpƒ_z¤by¥Sv§\oœ[d‘]nœpx±lr£[n’Oj–Hl˜Q\ALi=GW5GOBkjdš”`t“Vn‘{ÄÁœÉÀu˜–n€š•§¶¦«„™§’«œ´˜pŸ•t¬ž˜Ö¾£â¼£¦t‹Ÿ…«¨€»§tˆ‘e3::D7#NG"=P-4L;DE2`K(lc@u}S±t`|__wf;tT2XIA>:S>!b[.†nE˜Q‰¯l† pD°[iwur1RoBSx^cpK‰q?‘|Gu{XysZ`„JzmRŒlB°P`—P^zd^fBxi?hz:nhLpdJpeNuSI‘hDÇ^@»yOÆ‚i£‚fð†hî“a´©˜•“žvuƒf‹YY[D±VMÿ_Lÿ…Wÿ¨‚ÿº•õº¬Ö­ªÿª‹ÿ²pÿÑŽÿôÅÿÿäÿÿÿÿÿÿÿÿ÷ÿÿâÿÿÿÿÿæÿÓÎÿзÿ澜ëä®…{¡‚ã”_ÿÊgÿù¨ÿاÿ×±‘º©ba}bfK;fD89/)j,ml:]yY8gT8FMZH$8|¦ZKƒd1IE9'UG6o=$6/=$4>H8/Ea&uD&G}B3T`5>'L>%UZ"-nYC8 J` Sj+Ug5ZV.Qw;ap8Z†?t…Qg¦_x«d±hiªuU‡i‡w@“°Yd†nƒ‡6P­ZghAM“IT^;…h-hf>JlWhj6’ŽH‡´n{›xv’]l’\kyGj„Xl™Ph‚FS`=ib4Ž„<ŒÆyœË}ÕŽ–¾~©ºo£Ôƒ ÙŠ†ËŒ¤¯le¦~RƒURo9ct9„D¾à…mÍ¿Kq@UP$‚a0ižW{†Lr–VvwYa[Gm]8cGÙ“W›ÿ¼^™~t~KL‹d”f1˜µmZmS€E/y‹_N†RXK0IJ2‹`,¢YÕ†NŒ‘h|~Bab7s8˜¹t€Ša||KJM~z4}µf`„PEe@sd.`‘UP}>7]%UI"Mh;Yh.V€7cx3§‚Mª¸„{³‚p´i{ `b}ViW5pb@ž¤e͆z­^q XvQ­¿k~Èi¢XSŠ>Ir.SO)h†9Gg1MA oW2–L|s@‘cB©qIŒUtzJevDozEiŽWv˜N‚Hr¡\~Œ>axFN^-KKF> \l+‡Œ?’®wœ¶w‹²v•º{µ¾‚—Íy‚±c‚¥\qxFéoY|y^‘E‘åkéÜ}íñ±¦Þ‘‚LŠO®°fµÈ†dnLP‡HS‰C~§T¾Ê{åᛯ¿}´Ìƒž¼xq–Wˆr?[D265SJ&jc6Þ¥€ØüÊU£S]W4ŒJœÉpNi1•|gVlAhfHbv;{wHÉuzšµœ~¬h…W«†g†uRˆ®rv¦V}•Qo“J{u>~€L£U—Mt¥JKu3neG™¢nãöÂÛöµó²q§\m†VoMtšFn­My…P´ž|櫦Ûï´—\€nIŸm`™ŠM’N¤¬hÆÃ…Ãé‹~}T»‰Œœ±oeGYGŽ©Y‚|H‡™UjŒlE7YCK>7YQ/joBwQ€¦b™lWdm{fq€9cwKeyOw~TŒ|B¯hP|‹buuge‹K‡sNˆ}D|\{wVVqNUgCY\3O^1]X<[XAga?qY6riBžjFa8©ZR£aFÌ{RʇYÔw¾˜~­–„‘°zz}€^TŽ]E²oTø†Sÿ›aÿ¥zÿµ“ÿ¶…ÿª“ÿÙ¢ÿö¼ÿ¾Ÿÿ’‹ÿ«’ÿÚ«ÿñ¶ÿÿ¦ÚÿÿŒßÜ‹¤ȪtÿÁƒË¢{¥‚þ—lÿËjÿî“ôÑ—É ›Wcq62JaJ',s805!"#,0%2*"<)TG&nt8vlFS_C-UF*#;"QK[P5Aa5;=&%C"F-!3[#g8WS(,[X04!;4gL 5sCLI,€r-ou/_N`~Akp>€qF†™B¢¬d~΃}¬jr°k£Žj`šj€‰CaªXVxKƒq8O®Z~nHbˆUS„SLg;Haƒ{K¢aX‰Yuf3p–BcNa^HfdKO[MPI-P_3Ib0kj,ßu2K÷®.RA?JQq(ib/T†JCR/2O0>9yg)µ|TâçtÚÄCeXpW*mkC·‘KË—:\MM<%t`4x›g˜°qpیŋRá¹pq¦|œ\5zRz‡Gs˜M¬vG‡·gƒIy‡Vk“ZT}FTe2m‡>[hKyn7n¡QJ‰^cQ!Ig:X}-et0grDUS4¥ŠH‹§{–”^e`ZaowD|nE~“YM{O\^3}ˆF‹·d‰T¬i[MI|2X^0n~7XƒDg€BkNz°^i–CwŒLurGpi:p9vŠKQ:tQ-w“co¦_iŠGV;S~@U‰GFd'GV#\l'U…>iP(„†P¢§ii„T†r@†ža¥i’ÀicÉp_n5o}Dµ˜\¯‰e²Æj¥¾kŠSvŽJ‡“Eœï„Š‘OËËƒãæ»¹ô¥Á«på†Á„ºƒu­z†b—†h‘ªymnLM–;‰Q/œÈ~šº”¶oj‘Rz[XyD„d7wO³[spH|cG…{N‰|]“‹i¶|k…ªz™ŒcºžuŸÇrˆ£fh“BrŒ@j–Qkv@œ—k™í…´X„¶Vg‚FlrC±œ„ÛôÇÌéÇËà®}½b{‘XoŽPpG„µ]‚ž[®Ä‹·ØˆªßeD`v:CU*_\2hZ9Œj[nu@¢†^„©\gg?xgLf|Tu„Yª›fft?}ŠLs‹AH‹ŸI±šM{…;[s8Qp7jsFr…O€£]|—ZǹçÇyÅ™Vž“J‡T’”bδ‹ÿø°ÉÖsœ‰Wiˆ2LQ-D[59Z3JP,Ce+OS.bN17s3,>:&6D/;f"_L$[{8w_1_r9cNZ{?q}8„²Q{®t€«p|¼j{»o‘³oo¹z‚›v^¯[S}a€o?k¤T…‹WngfwK“xObz`ZUN`a.EU7RC(g[-ƒ|Fz|HJjQYm:Pg.9U5:@²P"Œ°Tq†`x¢eR˜NLk:V…@eY=~yBX¿X5„H?J+5V-?\&Nd+@]+qg$˜†:`¬‰Z|@?g+CM%Qj-Wt6=u=_/–~Cݧ_Œê¦EukP^4Qp3\l<˜†FÚœp_€thA­wJ€fšmJ·}Zï¥m¬´ƒÖz`§bŸ‘Z‡„K£h\€P‚2V‚’bN‹OUs.ŒZ6nƒOˆf?ª—G„¨tIcBTq.Q{/Wl/v8‹£m¢žY[[¡keoB[›Nqx?y‰G^nEa`.a<§LŒè‹¢ñ‚„ú–t¿c`’Pa€7Lx9P_2Š€F VŒŒM“‘I‡—[“C¬U‹›lyK•’H‚‰]m„R;:'up.™Ç]^²eo‘8Á¸}{Í£P–YEr*W_2x‹KMvFQR,]q¬rJ¼~P³Ÿu”w`ˆbFŽkO¸kW omŠ`OŽ‹PÁz¾^‘ŒK¦€G”{Nk_:uW:ƒƒR•—h„`ŒzM¯tg¡o|©dœ‘`œ­b†¦fk’Ab€M3~~w§Ç|p™DBe/Nc4XcBsƒn©Â‰ŸËw‹¦j¥¡s´»ˆ£ªq‹›wŸgmœh€¬ƒ«¿™©¹‹˜š–䲂|V‹‡d¢u£•t‰YoYµŸn ¡Tx‚\ž€[~gž“c‚ŽNsˆGhƒAl€Mq]nM_sE`yM•g™°›ÆvzJu‡Z”¥dJjIm‘^‹¬zšÁz™³^oƒJUrCRtGQsEVuWg€‘µ¢¤½ª¾Ü¦ºÉ‚¯·t‹ZsŽY‚qº›y¤™fy”g|§^nVo‹\w j~¦bwš]uˆM^m=XpVmœh·jw«k¨i„—Sr‰Tw‡[t€W|ˆ`„kŒ†X€xdŒ†l¥–h™Ž_hƒƒt¥pšŠ|¯˜Øq—m]…ih“„jl`5_o>PQVdSo_@ƒ}D‡œS«n…­‰€ž†c¢€M‚yIlYrbCy~5›Q‡—_P§oBxprJHF};CXM_K9UX1hc=awHXpOqhBh~=`|M_zHXw?gkEm`7hiAKsXXhKf`-Tg3Rf^Qe[FGcAwk.k¦S‹©e‰ºs•£n†¼uw¹…wªoŽgb—dKnXw`3‘¥Kž•e?skKR,WJ0Pn>TkERb3\S4_X1uz?d…Mb\F[D6]}7PmGBa-]S*lO-ŠŽEÁmˆ{vK–©mN‡gCX=R[(s?—ØwzÞ€gšh:lGMI'`y;eu6‹t4a§cFnE@b+JX&a^,X‡FhO2p‰OÏzD¿ä“e·ŸsŒM^PQj7f{@WpH¥T6ˆ‚XÊ}QšŒj~z_ykSü|O²Ö p‰e‡_;¢V½S˜_t‘jp~9s„B–ŒK¯¦VI­lFa0p[,Œ|Hº­n}¢h¢•[Æ^lSUo>Tb1tn6œxLd…fzo;z hc’Q¤šS»·}…®lRqFtˆ:¡½oÕ¥‚Ÿƒ}ŽwQYM^R*`r8b˜L_{5R|B]u3yy>p§W{–PuŸab™IyŽG}›YŸ¨gw³j¡›Vhæ†Q}2_Š6Ni0tm.q•E§žU€¿Š`‡JXMZe5nœVY…N[hLcn>›ˆZˆxfs`JªjP€Œg{PB“dWe¢ic{?mKWn9BV`K%‰‘YŽ«]•„_‡™_†ž]jÇdƒÀe·ÔˆÈû¯ÂÙ…ÉǨžU†WsrDÊŽ[ÊÉ…µrÂ|°§‹z‡ao]K…x]§·uW„UN¡fOz`N®lP§¸}³Õ—¨å›…›a›–jˆ—_“›yy©Yr•Lo‚D‹‹Lb”Ct…Fˆ“On„O}‹Xr‰Ds­Tƒ XœÄe»“k·€~žrfvCqˆKfKfNRq6gr5f„:k|Ao›ToKkcH~MбXµ¹màÌ‹´Èt|‡Q¯—dçºsì–kÜueä€i¥yR†tKž†M†H¡•P—˜RŒDŽ‚>uu=†~L°bŒ¦]˜«qÌÎŒÁæºË¨«_º’c|“J‚˜T´Âd¦I…£a™Åƒ©Ý””Ôˆ™¯m|žTTƒ4Vk/^u4os.`W,‰b>O‡žZ€ª[¤¾w’¬gœvIib5<@)64'f[>€°P«¹\¢ºWzS†–b Z}Œ\‚–Y_cLsqD]X07;$A6*lV2Na1U`<{}]”›Vec:Xd[‘L‹rPo»[`‹ogkFv~Jv†@wtQe‰b‡aCic>qI7œL,•uPÞ•y]ƒ^pZZ{]4qqV^YC`bAfT0x‰H|¨Q]ˆSR“MX‚Y[Q*hW5|p˜\\‚TQP1qj5^ŽXV[5yT2œA¡¡\ »}Œc]jCLg5gW+l`:^u?Dt;_],_l=i„:v±iyqKglH”V•_~`…P©˜j¯®‚¡­ƒÈÈuËÄ~¹¦|}•lg¥g^­Sd•;†HX}E_v8xw-£°x_”VfnbT6YJ0XF4j\B†tEŠ}E´•W–SD…{Bw|F”|W‰[foA—j¡È…¢¥c’ `¯ÉwŸ·c”’K‚C‰H|I}R‡”^‹ŽZŒœYužF€N†±Tl“Mb–Cf‡@a‚=s…Ht˜JqšKŠ‹WФ]s~@]l1txD‹ŠV¥UdwL—™_‰Q– ^‚¾c{–Y–µa‚¨^{©kq·nyµ_]?B\5M]7Hh8`u8lŠ`m8U\7_jN gw™VPb:cUC„rd¯¹™Öó¯Ðÿ’—»r­ÃÃß‹ºë‹šÅy—c§i…`ª˜x£‘WflB[nFq{m—©ns‘b’Å‚›ÖzŸµq¤¯q´¨l“›`v rœ²xŸª{Ôªv¢–`y|R…Œc›£p¡¥v­³†Ä»{•›[y“Ju•Rr–Rn‘Mmw>`b/Nd6Ux@Vz;M€Wr¬s‚шxÅkxtŽ·~}©nzŸg~¤u€±e}£_zZ}†TlMuqKu…Ntb„‡d}^rži|¨r}›crƒPt‚Nt„\lŒ\zˆau‡ezšy“˜d…yU†€cˆ„XŽ‹q¢€Á›s§•m«‡lš„ZІGjxR`€_qnŒ¤l„™`uŽM\~GUtJevQa…`\…j\{SliUnƒH`Œbx~fK‡bR_XLbJD\7RU3u[)c„9K[WRJK\1lO6oh9…rMz•Yj£hVŒV^yMYyFZuIPrANoGk]3ai,^vMsl?k‰Fk|K`~GYwFLx@]rIt{:frB—mN{u9f€\kfWeDi8}tDosJwdMyrD‚xV£tI‰ŒOkSŸcEºoHo€W¡s[¡£D¤¦n›«zw¨wzsowSC~`-†:?0X[+j|/D›idi7>Y=SN!=P,D\.Rf-6g:5D3nC!„›D}§YbjK{ETc8jW‚pAk‚]OkWcP9WnGXh@\M+Z|4~B{ Y’œ\N•icD}§Q› ge¸l9FK7.#~T)‡–Vn‰oSs_wS/½jEÐåz­ÿÍ¡¸Žâöxÿ¯t·vZ’Q]t:Nq8…n5Uy\PtA¬•B¼ÇŽnÖ¨rtSHl?iv8hŽMÒ¦N¼Ì¡zÿfH¶³¯¥³€‰¥r‚vTPJ7‚^3­²\ogµƒWÿo[sÉ©u[‰ŠNs~Kœ‚HÑ¢nu¬yyH~¨^Ô³^Œ{f‹T~pU—_£XޝwjŒUHUE[P-^cЍeoœoV|I_hDnv:jwC˜Ãbª¾r“„[ŸŠVŒ°u‹ÈiyÃXo¦VažM[|9R>kt:š´jg®ie„CezDJg>9]6`pF~‘ln{RfL3.B 6F&ZX5cŒX_q>[nAPo0NN(PJ)¥pH—†Xl…Jq«VY•>=R%G:€a;Î¥wÉÚ ¬†d¤SŽ|O•’TßÖ䬆µõ™Í’rɼ‚“˜Tv…PJg9??&[N2pM8¨XNˆrRlP8N>/Z<.s\=‡tIgN¦‚_m€Rdi>qt=\y<[v3uŒMsˆDx†G“šX‰”^dKn€FstDc\/b{4[I6‰yLvn8Uo3Eq/Ie4jY;Ja.O`.nxDyŽUˆ¨hŒŸc–¦a¤hºœ^³·U¤ŽS¹–a¯¥¯¿s‘J‡F6dc=‹gNykEhF5s[?±td’ž[Ê\Š›Hml>v^Lt†U~vK{“]—±y—’kžŸ^© gñÊ€µ×qˆ»Ys”I…¡Zƒ­^w˜N VnIšT¥f‰«d‡žPŠ‘Vx’Pˆ ^wŒ?jy7nrHŽTj‚Dhr7vvL€~S‹c¥ sƒ¥X‚’g˜±i­¾y¥Ís}³XmN}|R‘²›ÓÿȽÿ‰“¾~‘±fˆvLˆxL‚?o†<`|;Pc6hhG}bŸ¹•¬ß¡´à¢˜×€iµapve®º¢ÆòœŸÀ}¿Á†µçˆ¬È“¿aw„^‹•h‰œl x—T‚uKirIxrbŒ“t¨Á¨ÿû¸þÔ„ÇÑžóÏÄ _Š›oºÃ¢Ü¯|¡›i–£m—_uŒ[y[Œ“c—¤x¡Çu‹½Vv£Mm—Kw|SŠˆ]‡ŸcŽ£Yk“Hc~D`{Kh‹Ts²€«ì·ßÿ£¶Òt{Ÿo†²ƒ¶uˆŸb€™j}ªfy f›e“‡\˜}M~CnzEalHWpZg|[m‰WjŠ]x~Xu‡Ut‹]p†UizLjtMqx[~‹s“•]ŠuO~uZxŒ_~™m§™p¢•ožj“œg’…KyGezWoruœ˜´‡ž¯~“ªit—Tc„P`‚?Ur\rbLhrCdvKfsO`pKTsUYiYPdI`c;Rf>TnAlZ=i4t†Hm„cXiJXh@Pt;fh@†qXb0We/¢s7½ÛaÇôŽžþ¨Ì’©Ñd†ÌyR›gNlGEd,Vi.Dv;0QEoA-Jž=CeRfb4b‰=Y‚SGvH5]:WZ0k|<Š‹ZxŒOu–g˜ˆc“Ílb¥–BckK>AZV-{\2q†NcˆTbnIeZ:]Z6\S7`7‰g7I{gHC6^>+VZ0CmjPl‘JV”JbDMšR|{<^¡_‘{VWÇaAoM8K-D:7CTH!Ko6Oh0V_;o_>xŽDbYWiPFm2DL+XL,d~AJhVWH2Pd7XoI€wCh–^pž\vžNbnRŠyJqªffomÊQ¢®sw¯n}…aBŠokV8\‹WBJAqG1fvRˆlT«×dÔä‡Üð•àÿÎðÿ²žÿ»y°l^–jW‡Bdw;]v0wo<¶ezST·šPZ¸•ClD\k4ŽL¢Ô|Èé~ŸbgB«e=›jWxx?Œ–Rj‚^•ŠKŽxVÅZ“€h™tR§Žn[“iž{DhU±n7É…T¦²syœ`†‰[³{J¥×‹ˆ›k·¤oºœƒˆ–yœ©\´nj™ckrJsMqnE|Ps]h}F€=€€Rs˜YŸ€G‚˜bb|Hg:RˆE\q4t8¶‡Q’ŽVj‰M›·j²Á|Äÿ´¿ôœŸki…XWe0_[3fv8Ÿ‚H²‹sZ\L\e'‡Y‡±zXƒ;]g/…Y_|Dks;Pˆ¹up£vEn;GT,BU+6F!I[2Ur@DL%=\#Wk0yœV‡šY|¤]UžT]v5tŽM”®wIfI]5„`>çpOÁ]ĵb¬™`Õµv»o^‡8mr;‹mQxI¶‰e’^ʆ`ðڦŹ~ô|­ÝŒ´©tÉ™kˆ”Y‚tE…‚I‚OŒ‰StGœdV’xJ‚TmpC‹xTÞ¥€£œbžŽ^z…ValE`i:h~EevDcwB_f8~No’PUh6[q6ez=pVdšSQˆ\{0[}4r~8‡M¼Û«°Ëœ¡±…ª·…“±eƒ‡}Ë⤠Ät‰¤i”»l‘´\~JdhCjpQƒ™mŸ¿‘²\€“b¨¤q¡œrŸ~ Ä“¾µvžqæÂ©ÿÝ•¥´g…«x±´v®c¢r”£p˜ q–”Yx‡Mi‰Lv¦c±Ì}¬Ûp”Ã[z£IlrAf€WtˆX…‹eœ“\‡‹KhpBj‹r Û¡Æÿ ¸ãx~¥d|˜v¥¹y­cy•^uŠ^w”]wapWhz>hxDf~NkzXi{UuUqŸYiœVcOasKpyWv‘^v‘HauF\yHjvSkg„\‡Tz~VuŽ[q[yy]„jW…‘kŸk”†Kmƒ^z’u’®ª†¥²‡¼µº»|™ Z‚’[}”I0bTD=4a?!eW.F`BlJ@Mp6:eVR?;hI,^`7R~Ga_Pg`?wrCa…PnsTpzFWˆPhgF{nAm€L\z\^w^`vIIˆW\_H_n2`v7`o7ZoDVa9Tb4Vg5Qg1XF;Q\3Wl=`V+pW,sa;‡eF‡nAv`BI^EXS>HN%MC(YR*kg4on;`€SEhPEYCYZ2Nc4LV6S@.^M(gS,cg;ToBIO5\;+iC)WS7?l?N3.eL'›g8­ºN±â…¯ä‡œË€f±r9|Y=>/JR ob&o’AZ^eQ{‹CS”OLSGff4QvGTkADq@_sE|€ISŒd_TPouDs—a¹•lÆ{EØ­GjsVJ3is5cJ[`Gkb9WD^cCz\4rq?€tEd?TwQcTLOP4ZO2\t:“œKY¨^b|Hj8o¦[vºX^¥[dkO[`:\>[±C5db6R&6R'“Kœ{N•“U[–cn`/qDËœZ‰dŸÃ†{™b§¥a™«t’g¢Tµ{V‡Ÿmo’IQ‡Qep.Rs5fe,vx:lwBge7x‚Hi‹@p}?v›OywDcxB^s>ˆ„;Õ™ÿÓ•ÿéײ—vouM[[7^a4Xk@^l1[„H`{LcO„‹W wqzTRn7w5w¤\oYfP‚P{¥fqyDd’YRu>Uj8Pf9Vp:`ƒAoŽNx©_±asœ_Z„A|h=¡±uˆµd‡ž\re@bT9ƒ]5Ÿ„\Ê€Wÿ„hÿÿÆ®ø³šË‰ƒ·U[S5qg@oi>øeO½z]©‡[â›fÿ¸£ïÒáÌ~ïº‰ÑØ„¸–t·”Ω„ÀÊ„‹—L¶œaº­q¥©nœyYëz\þ¢¨¨wƒN¢‚R¨€V×¼‘’«sl“Ms|Dkj9isAVq8foBd„JZAhˆNeu?iyIze}“c…Vi¡HR\*PE(VB4Gk,JA&KL-Ÿ„RÈÿ–®ÿ{žWƒ„X™‰h¶j›²_‘˜\›~Z³‡]ИlÌ©tØÿ§Æÿ“½í‹ÙÅ}¼ j¤›[š¬O¤²Z’“[“Y{}F³¯y—°mxwLއXw‡U¯•uÙ»ÃÛ„“ºe¥×sÃχ¢Ì`€Fy™HmˆF“§iƒ«Ra„6c@z‡Mx?yH‡ cz’K•œ\­™N‹—N|«Sƒ›Qp“LcX¿h˜‚]œˆb—²o‰µ`…—]xTu}Lk‚P…tC`m;au<|yh¾Í¾æ„©Ùp‘¯k©Ãk™©X¥VxŠ=`~4Y6\|@sŠNw•dž¨zš¨p„¦ƒ¼Ã‰ ¾y‘Åwy¡Y’°[“Æ^“³Sd’@W}@]W¢½ŒÞÿ·ÿÿµÌÿ¯›öŒÅŽ—µ‹ª¿„º¯rµp̱…çÇŽßÚžÁó²é|½h¡Ä|§Ësž»m°£[Š–Jj—KgŒMx›a£Àv¬Ôh‡¿Se†ForZ†”QmŠBs™W–NjyBq•‚¾õ¢Éóz†¨\nŠUx”e“¡c‡‹My„JhoFeqUnˆ[{ˆTm‹S|Ša•h–Ÿc‰šc‰™j†¦j…¥fvžaw’Vq[yœ_xœQlŽGc†Fc€Kf_~“_s†W€}W‡‹Nk€QlxMwwR~{^špg y[Љq¡©}°£v¡Œs”l£šx§¢mˆŒOkoLpuV(\:=56TP&Dn1CV9hD+[d2AnMFQHJX5YS-gW6]xCnzV‰lF{~EwˆVW‹ZPwRec?kj8j~LV{YgpYrrO_“TSmX\^>af-ThZq8uVDiu:InE[N0XO*YO3`I1o^3rR?CO6FY2OS)GN(VP-M]3kX2wm-eXOpWSjESf??hC9M.@T+VH(PDY[1JX3P='}?%g\.=yN(03X)„M—¿MšÚvˆÃYŠa5KG#P*/6"H:]aHc2WH9drx†GZfJbOXZ7`qGnšPZ…X„FtdDjaGayR…•L\‘fSZNzc5_`Ip‡O†„Uw‹R^šRlK:¨R/Ѝ|¬ºsŒ ‘o´Šxnm‡U”‘]¬·dçÛsÙÿ¹ÉÿÃßø–¥ÿ¤—´w¸±oi²‹N‰D´šEU¹„`iA]Co^:PjAK_5ªs=“…[Œ›uÓ¼jŠÿ¹uj[zC{pQWnLh=ž‹GÉ•^ ¨‚…ª}Á›i¥¡zŒty—m[[|‹F”F¼¤_x{o’bBvŽO_n”V|˜Ut’XŠNгk—Ža”²h¬wn—fqoHjxAjˆE`€?[yIv|BzŸUf?uu9R^2w[-‡{Gr†Skj<‚i4yŸ[uvC³†R¾ÿ¦¯×±›žv¥°ƒv‹cvaI^yIgp5e‡Mfv=x|Jy|RŠ©fdƒPXo;G\-`g(„šRl™[u€Nl…P|Mr‚J—X‡\nªXŽ|I®±wγnËÅuk›`ƒq;`hBJW+BX#>R%ªjNv¤sUX4TB)†f:Í¢lɦw¤ã€• Xÿ•qíפÿ¾¬¬Òµ‚«nˆœj£e®dη‚ݲtç¯uî¶~ÿ´™ñ¢ŒòDzÔÕžÛ¸ŒÍÆ{ˆ‡SoAŸdgr8ŽkG­gU·ˆjVÅcS–j²˜`¦X±|`ÿßµÆÃ˜n˜ZW[,nhC|ƒUk‹M^~Bvh8zŒQW} tKoh9jP9dQ*wsCDd.-740MU,c‰Mz›SŽŽTÇØ†¸±—c‰ŒT|^IÆtoÙë¢Íò—›¦e¶®iÉ¢uÜÃŽÖô•¯î€·Õu©£h¤¢i¨”T¸ÇdÀÃjž™d©šY£•aÖ¹‘ÉÆ‡¬¨u“ÉfŽ´[›šh´¨bž¦]}žSŸ`‚¡XiŽCf‚Ce‹Fk—Gw”VwœK_‚@e€I†”Sl•HaŒEv”Nq’L†˜Vž¨V‡œ]Ÿºwž²i——c†ˆRopFŽ[N¡yW“tdœŸs‹£c–Vj”O‹¤k‘­Yc‡=j‚:wvL£™o§ºk¿aƒ¤l¥´lœ­a¥£WuŒ=_†?h{NuŒZ~ˆc~™c{“Vv‚UŽ}k‘Šj}^€ g{ j§`jGj–;gIe˜\}§f~ª`ƒžv©Ïˆ±ÔžêÿÏÿÿÚëÿÆÖÿ¥²Ý”»Ô…¬µd˜±ƒ¨Þ•¸ß½Õ}¦Àu›Û„­Þ|²Ôn¡®X•¦X•¬`­Qt§Sr¬]ŽÆi›Õm•Óh‚²UgƒQrKs~Cj†HsOuH„¦sÂᇲÑmu™Ed„Ku†ZŽP|‹FntEhmGj}WˆX‚‡Uvfzm˜–b‰¤_r¢Xe†F_tB[iNo{[ƒ’e…Ÿm¨lz¥afI`‹K]‰G^…\n•_}ŒU{zQw~CbnJcuKjyPryU|Z…ƒV‰—j‘šiœ‡_…tU|b„m‰—evCafMewdDVAeH5sv59}O^SKrU*[c4qbEh[@XgBReL~]E_„:D‰^RaNyf1xp:bSdpSshEskAuTq„[„†Yz‘VVŽVGl[U\>YR%dL'lQ(•f4xv=woG„o?›‚GU§ZLcYYT,YU/UJ-_M3h]8]T4RR3Ad2O]4KR-SW0GY4gb6‡t2h‘Ia_ltJe^=ZkKblF7}J6JJO1F_!U^.ST*xH*vY/9sM"F7X%Œ\ ’›E^­s/^`5@6+H$96-Q%;B&4T!'C%O1Cm.ao=‚„5‹½[n·p€¨xŸŸb^žsRbkRh5TTAwK1U€?MYK]L7ec<½d@•¦Su°ŸZlTlL>hb?mnO}a=ojGŽaJŠ¢VOŠehT>LCWcBad4†K‡¦f‚¸‡~Á~Œ¼q‘·m…»s~ g^‰\+\O@/0PE#~e-Mœt:_9EM-VV#ko6£ CHÄz9R=HM1z`0_”SDRHgC-‘‰=h¦xq‘iWšgZqEhwHewMFzLOH+tb/“<`_lYFx‹HYlMElFs@¡ŸZa­‡unW}]Fb‡gŠhD°Ò\°áŠãë€åèš·çìé“ä™—Ùz„¨~gÀy«™T|¬oGs[e\4`‚>Gj=MW-¥n:¥²|¾…c¶‡oÿÇÿþX~rwzA„ŠQ™£c…cÖ„J“­uˆiJ“vP‚™auzH†uOe{cuzEˆM~aEt|E_j=‡‹Hz”VYgP\F3ˆ{Dj|Y³–OvƉ£†Rz³|e|IvU1\lBXj2[f/Sy2uzCyy_t–q[¢rWzL^–X`Ÿ_ »eÍ„iºpSx>uB~W°±e’²mgJ‡Tp«xZEŒW;pnC’^vN]p=­f@­Ç“k¯z…t;ª§|^~L\…BƒMˆ’grGiT{›ZŠ„mX^7mBŒ­t|‘V•ƒGÖ©|ÕΓ¯_Œ†T˜ggyIRj5Gn2PV+GK(g_?”oS¡Y©‘YЛhÝïԥ§v¤œj˜wMµlÿÀ—ÿ»¬ã¬ÙŒz͆gⱇ׳̞jÀŒ\¢„c¸›n¡”fª­qÍ…c½¯v ¤dˆSx™[¦ƒFÑÎuÍ«f‰„Mž{Fš‘_Ï…f·“f¤“jÿÁ³½³ˆr†M^z8•jJռޫÌmjƒJdn9x|Lh{Cqz>}x;me=iU9dP7`\5EI%;:48>:#™|^ÁÿœqŠI€”Uig4•M‹SŒaˆa¹µ†Â΄®­n«§_¸¥dذeº×wÌÖÆÛ‚¨œe¸©d¸­b²Ógľc»ªZÎÂa»NŸX‹OІU¦Áy—Ïa‡T†–[mˆGcm3n…CFJ#_N"gT%ŒW+§d3ЇHKd@bWGU/KV*DS1XI.^d0hm5dq:P{GDjDUV2_Z%g`1vyEb€DaeB_oANvNg]@‡j.tˆCC‘_-aO/A%B(GP]S){Y*jb0Sf>9[4T`P4UO[XI\h6MY?_G0¶Y-žžSb¥’b^[}m>kO|Is²^ŒjžS˜±lÍpmªaZTv‚KrœYr”p„Y€Ž`ƒcx¨kO™jF\UGN1gšcO_[pMdyGE‚E2<2f7Š„?r”v°qYd͉T…cl{HS•^WwIPe5ee4Nx/L]9Pc1uc5NoOdn?zpH‚YJ’sHžo”`hmUz}B»šC°ð†áÿ–ëÿ¯Æÿ´¼ï™‹ñ‰Æ²d´à§À¤žÂ}g¡‰kfJS~BFZ>N^$BT/xz2§‡JškX‚zN™_>ÿ³w½ÿ΅вH™]©’hw‰gœs;dwHsZF^P@sg;•sF€wYX„f{‚BsqEhE`p@fu6|M0‘H‘\B΄^œ¬^|T™„Av™s†K^pD;[)F]%GW,Nj'cn)k–NKwLrf5eoQjQ+|^(‡oB ‡N«„Z€œ[¸cl¯vmtF¤¢e‚—nN™er“l€z]_xSmd6f|?‹L1taIop@”~T‹µƒuŠRžaЉG—lEŸ—q°¥d—•lz›g{{KpƒX]sG^uG¡†W~¯z€ŽUt‚WÛŠQÄÅŽ~˜pxž]xRZw?‰tCh~PftBMl9rh9pTº„Y³£r ©n°—WÛ‘r¿Œg£Ša‡—`Þ¨k䨊ÿ¤¢ä؟ٸŠÈ£gÀšb›™c³_¹¨j”U¿b®²q¾‘[«šj‰yOˆ•QTÿ©qÂê§Â~[Æ¢k¹‹fqs@wrLŽ|NŽvRžkê·ŠŸª†…‡Y{zQ¯¦fÿ´ÅÏžeBkV1dm?\o[q=dpAafGuhAh¢X<~c>X=HA%ES(5I6HB%\Lre)os8ikLVkIddFW)iO#T^%Qp>io4p7zˆCN~P?dK5S*F8&LG!6c%;O*FWjl'‚?…±fw¼sv m„›`u³jjk]—c9kRKN>M`/\g6ob2€=Z™WgZCaq7Y\OUV1h\9À[5‡©RŽ…„¹•P¥i¥žc§ÅtÁ€…¾x˜£a_–eY~Wj@k‰ILPMrG]r=Qj:\bE~i>Ž•Ga¯jf˜ah•Rc„J^dApbFG“UPnKI_4,V8A- UB ’a1uƒWdWhrX\“T_‰L~‰Gv™\e–if‹_€[WnBagAm{OtGaj6R_9`oQ€Žc‘žh…k„Ÿfƒ§n”®}š²x¨dnšb{™gt`t‚PluAan;as?gsBfyJo…_|—XvŸ`p¢`sž[tš^f‹PhŠWp‡[…—e¢e}žWm‘QbTcQx…VzJf~F_qKnmNruQ}†[wŠl„–e‰•Zx‡fusKZ=BU62N2&>1-=%+:A1LAF\4IL7eI.bg2X}OWcXd\DvE\qJfoOh>Y‚LbaSh[7gl:otAqs=‘@S·bLnzJa:QR-OR/CD0HA/V[3Yo0jj7qp@WrCjpQtn9az@k}U‚KžLt„UQt]=fLMR9VO,EL/5F+HF'ZC^S)Yq=Ca6<[Y†@PyQUe0Po8;a76J./B E;DU%N_-Db2ZM#tn.z£Vƒ¨aw¸t j{­co²syžmZ†fRmPZhJTFPr>b]1~h-YH~tMW®]Q^SIW6[Z4h1¤—H¡Ì†Ê|“–yŸ§]‘»}w³vb‰fN|OVx@au@WxKXyVc…NJ|MJ[3TVSAcc1H‚HBQC?Q-,7%.4:,‹= †ƒHJnVuh7m—LxmPy‚Wi hOahvBd{b›_0g³}I‡k4fE;8,b"k•Cƒ|O°•NVŽ|CZ>X;,zj6gnWŠ]:‘žPa†mm_;x…B¿Ë\²ÿ¾Ñ‹ÇÊ{Џ‚n’b†žC—µ]µÃqº‹Nv?Rn0kz2Ol2JW.?]+hW!x|@q|Ho…MvpHMS>£Y5ÿëŒÿÿ‹y_}sWrUAgtIp€Im`JQiHGH9kT(sR0|MyVW}IRJ*\J-dK/€O8Z…~ONLBi@'yOR|PLm3Sl5Rc1];+oG+wgAb…CKl8YsHTuI^tC^šPVlAr}Ne~Q]j`i9bEkFº™\ž¥uÄ£ow›jvpJ€oFšwJá­†²~k§iŒzQx‡\‹`®¬€Á·|±¥w•o‹mBuP{€D•k>ŒwDvyGƒyCjxEiyJŒyC¹„T¯¢eœT¯’[‹©[{‹N’O£}g¬Œc›ƒRª«~¶­~ǦyÅ™r¿”kè’„¸©…¬ŽlƯv©­rœI®¢Z›¦^£[²ŠJ¹h¿˜lĤiá]¬á‘¶à„´ÏxŒ|S„sSwjBh‡B°˜g~˜Tƒ‚K©rZ•™t©_Þ´”ëÉŸº—k¡‹c‹g¢ePˆi›wPˆ§hªÒšÔ…‚JqZ9©}g¾¶´Þ ®ÍŸ¬½‘ adw5nv2ÿÈ¿âÿÅbtoaAn[:UZ9UgLj‡\ˆ‘p››qŽ“`‡Š[Rs…_†—oŽ«vƒ½ŽšÎ‰‘Ë‚‚¯Xq‰Jdv=Zr@]pAdv@jƒIv¡]†®f|¤_l˜ZdƒNf‚QpStU|†ZWŒ[rŒMzƒNnKn‡No~OwŠVr…RiqLpuSs„\Œx —|Š˜cyˆYhyZWNCAU,aJ*‡N#cq;wsUofMhJŸŽRyvWtc€MWŽ^]QWVL8TW,Zb2^2Ÿ~5SÌ}NzšL\B[S+M[*fM8uY/lj8`dB`a:Vn:Vo8YmAqh5|…@†Š]_wUVhLQU?P_/Wp0fl7RO96D62?$ZC gUg[3fW5Vn:Sd4=p>ZM+bi&QnAQcE\j4yKœ§axÒyJ¬p5jSND*Do/?e54X):BD<=< 9@,0R+I5bUnl7u{LgQsˆ[†ŽO{®g[¦zPh`TW9cT/btBVsEPe8a^(‡f3‰GxÆqwz}orA‰€D¡¯[½Ìs¥´|f¦‚ukd‚šRj•iI{]Wa;cr.X„EXjK_w?[‹Y[V>ˆ`ON.I_9U_6RvOMX^66zA6B6.L1/,2/:"O4!—P'sFdoMgwYWIW~:pY9cpE=^4W_$j>rQ@Oh@ag+ph9’jEÿÈsqÿï~~ceƒTtc?`}Cvf@asK~aCksFRxBŠm8Ž‹`ƒ’gc[Rr?ce?zT;ÕV„œ{…ŒQiŠXZT@uo7´tTŒN…l7–ƒdUlKlg)aNTo7YoCZm@j†Mr~D;LL';U-'P3/<(<=EOE^ DW2VH'yO%Ok3YaTgTC†b>žƒIƒb‡kQr‡UO‚^Za]hH;~`0lr Œ=XËZu£R_>i_5g^.fe9fp8__2VJ0SJ3eK6x\9‚€E–~O‚—VL€fKQMBF3KA'WQ%if.hp9@v@I5>8>YO&|N_r)PlD\X5^[1Jt;faDl{0h‚BeeOŒa<¨«N Û•yË\œ6uNHE/KT,Ej1/Q)#7#0.9?;C$/G$J7GDB[6R_3Wj(auBay>lpEI—PG^WM_2NJ0Uf3L}AOtBXr/uv?¢‰Gˆ®d{Ÿ~˜‰J¡²]´n¢rvjK~|=¨kq¤_P‰SRjASg/dY)Go9Y[?hw4g”]lŒ]M˜^YdHNU5lS6cm6B_AUW4or1IŒ>Lg=GnsCFM?0\%*:2(2+]8!f_3S|OON(ug7›HB’lWA?U>!jR=dQ+B€Jbg6ql6E}KPd'}t0V;Qr?†9V™X`SB`{:O¡QMŒLHh=…X*n¡f‚š^}^xZ›I™œ_ŸÔcm­g†A¨‹W|¿xDjS9V@Y!aW/V^=]~AŒh;U‘RN]6V|2U[B9Q%pRŠ@‡¤WÚž^€ÿ±ntmmšZgxKop;grB_jC_jDbZEQP<[N0jf8keIcJYmL[Q1‘oD¿”e‰À[–^B_C=3qW-‚HZtLoC¦Y9gkTZ}<[w6[~8p—Rm_]ˆQo†>p ]R^3‰a2hµqOŒV]h?ˆ¨i±[šib‚K{ƒNŒpc·„vtG‹|U‡¯jišaŽXP¬{@58>[?Gj,8Q>>.(RA Wb)[cA`hHs`Fqi<\cGnZ>wqAa‡RdbPoX?€a5giBŠd?˜‚=E¸…\o•WO2iW,o[,[`:^Z?[k=`]:]_:ZQ6#JS(8R094'@@L9GR1Hc7T_"ek4F{!6F 2=(Z/D]*IR5bS(€|>`£i+^U)0!:0:9Y6$Sd+Fo7Jf3Ze/`’7KtE_w0zr;›£Q}ywkv>wx@sE—ZSʃ|‚Tk•RJlIZg5Q^?T]*•q+w¸Y\oLrj6|¦U9n[:AD<MC(VU>knGtdŠOLaKDN,gm*NvJ9c.:ONLnc#ÆM˜ÿ­–xzk‚]zkAkU™“^† r„¥peqT^XsHc€Ra’^x‚[s£pu“_xY`rOQX<‰g8‹˜e…±lluWMZFeX&ol+Jq;Vn3Vm2{†=u—Tr{S|€Xn“Pu~=v}NYgAN`?tn<Æ™Z°ÿ¹†Å‡uNW‚EGl2CH/Y5#¼tJ€Ú¶Œ¢ky¼|ƒ”`˜›oq·TtByt>h‹BygAo_BieCmu8kjCpeC´yDÚ…t¾PN¥…s¡i\†¨zji7±`:Ì ‚ƒ„aÆW—žj}ž[jœUVd?|g1|ƒKsŽX­‰Oa“T]d9uk@wŠXvmIx‡C‚˜X“‘` wO§˜l‘‚`z–_~“Ptd@’oKœ˜k f™ŠY“…Q±„L¨m¬Êx§”c€˜l~yNn‰Ch{=cu*~‚6º¥bÐ覙Å{“TsŒS “`±ŠR¯—Z¯•dÖË…žÌiЉ^®œZµ{`µŠgu^jX‹¢p´Ä¡»Ýµ®Ë¨­tf–Ez‰Q¤¾dÊ·g¢ŸP™•d¬¼{x}QwG>yscP]:jYEX`?TD2‚mP³Õ„ÿëӳ剚^‰Q ›U°˜^ˆ˜P‡ƒN\€~H„ŠV‹¤Nf˜Cdx9oqD—{Y¥©`š·c“œ^±“e¶¨q¦¢\«š[³·k¥Ío™U‚ŒYq–Zw†Onx@vzH|‰Gvu:_q@fxG²ª†ãø¸ëÿáÇÿ´žÝ…¾o|ˆWzoJ€wd{¢_H†¦\¤»f¥Œ`ÔŠxÌ®rª ]†‹OoG~}R||R‘ž}§Ò‚›É~š²r†¥YŠ¡_–Q£”n¬`„ŠPš~cžž^~—P…™_¡½v¯¨sÅ®{£Â†ªÕ§×‰µ¼ƒ¥¬~¶®…‰‘m—Ž\€ƒKt’Tˆšg“¥t–¦d{‰\jvKv_u¡ZyždpSd„Ng‹Pq”X|še·—¹ñÇÇÿ·¦Ý“²xŒ¨u’¦z¤n†¬t›ZiyCIoPy‰qª­u™œgµ­ˆÆÚ¤¼ÎŸÇÕ‘©»ir}Uz€r’¢kžUtœO{ždqŸgv¢am¥Rx’QŠXzŒP`rAC`9HX=\[DkiNn~Iq~H[l8]f>lvMuxKp…Ke†Tp“f¦}‰·vŒ¡]x•Gd}=_{Prœ[yTvœRn‡Rs‰R€„OyvEep;]qDb~VjŠd„¥k’£f…—Ww“]yŒd‰ŒTwwXŠ‚[v…_ƒ…c‰‡SxƒX„}PvmEhmFhsQw~P|{L\S1_b5KuK4Z[0<895 _88n038HH;+`K"br7ƒmEg›NP}UQ]EhO7im3}hBcyJV]TSQ^]1wB‡CŸfž«[ƒ°y]ŠgW{Oo{?‰ŠF|…Vp€[n‰HulG_sHgnG]xKRrGpk@r|Dh‹UcˆVU„kU|c=sCIQ7Oc3UrJc‚EYKV†Wf…Dk¦Y^aYX=iSBM)CG$WC!2U)Q8&[I-VWA‘†? ƒMH’Z;PG=U1>L'6D%FG$Pb%Ge1Xp4Ts7\_.Fi4Zr1„z8€³dWhdKv3so9ZvFr{J†tI‚§^»xa°oM|O>Z5?H$tm'N:;B#|n.@}P4C)AD B@0f|Aaq>tk;[~G˜‰A‡‚P„gI‚{I¯¬q”–[…’VŽVm€Ltr@²{L¤‚^¾€Y½¡eµ–hƱ…¸Ä‰•¬l•©_Ÿ›[zQZ?\o.|œ4Š¡Lž¼olŒP}„N}Z‡yO†„IˆN…zM‚rRkY@ŒdA‚\B”Oœƒ[~xNqŽm¡¡‰ªÐ­´¦™ˆ˜x|oQncN~\BËšb­Ð~Ķl–¯d†ªcD~;K…Kg«jM€?Zh7gpLu¦iwzR¨ŽdáËÅʆ´«dª¦e——Q ¢U‚K”¥gÅÆšÛ‰jq3ƒ‰M¡ÃsŸÖmžÞf•¤P—Rœd¾˜k¾¤s©y­°i—»d—´g¡Ñu·¾u¬¦v»Î˜™Ìpn‡El?‘’Lv†Dˆv>{|E€ a»âŸüÿÝÅÿ›‘®f€”Pqk?wgM•bWÀ‚a‰¡K…­P‡¢XrqEƒ^Ib[>r^OŒvY–c‡‚Zo‹G–j­Î‹°ÌŠ¿br˜XŒ“U‚S†§m•Äpn•Cet7{ƒPˆªW‰§Xšœm©oÃÞäÿ°ÉòšÀë—¶È„¼“r¹¡{œ“s–‘k•›T€¢o˜¢m•–VhŒLe”O]Pl•h{®qw°gm™_p›fm]zZƒ`– ‘ÇñÔîÿ˺쒉¸s‡ªw–À‚¯dŒ§mºtˆ¿t‰¿kx«h„—g¢ j™¡q¦ª|¡£w–¦tw›`]Œ\fQWw>M_2Na>n_…—aqœWƒ¨YsžHs‰T}‘[n€N`zHTg6KJ0DI9QnNc–YZM\€@ZvHZyNSqOhš_m±Wi—eƒ¨ls‘Iv‡BjNu¤ao¡]e€Lb|?Ri?QsM]‡Lc{CZs7Od@ZzHd…FgyQtˆgªqš¶v¨ršŒXqsFh|^Ššsœ§n”œV…[ZŒsFmmHflMp{Eql@RN-TU52\B/DG18*C, g>#Pk8EYGYN9Qk0Kf>pZAXm8PfKW_E_V2eo8ekHUsKMQGM`XD,wU%¤{4XÈzfœdqP`oEtn@u„;z{NosMjcVhRA«W9Ë‘Nu›lVjoCLF,;-<*"D+SA!]r0qs=PmFGZMhZ5[r«g–ªo¨¿ˆŽÀ€VÀ“*…i2/0K3dN&ˆxAxxNE}J?L;CO,@J+K;$>T*EP?]]'\~4T6Pr@rg3=iHDD?JW'^P,@l8R]A^]5iqFYE²oA¬¡Aƒ¿‰ulkO^ŽT\fNhrAuˆEh~OfZ=kp=oaAanI`gCr^;Y]8]V;aZ8fqRK}VPoTO_9Pb1N_9RK9YY3Yf>}o;w¦Y`¢fC}R;_EH\)KW(IY9Vd2N[5E]?]Z7ˆu>S›g@K4BE4GG(GJ6TH%ec*fc3wv9P‰JW{EcˆIi—]k£UdL¦sE]=oR(ylC_‹Q^€I}xFtxE”t¡”Xm—Udn:^b?rT<‚fLpƒMjv@qFnafU<]V@nZ:ª›dŒ¶hsxLφUk9phBD‚;31/->?'gk7ge9qt?~`8£pc…­e]t>‘¦n¥Ü”‘Ƚÿ¤Úÿ£Úÿ¯ÆÏ‡Ä­„÷Ùµ¢Ív³k¬–f¢¦h¢•f”Z¶­¡É~xDj€@‚¢e´æ”åÿ¥àûŽ’½[ˆ¦]¥^¤­cÁ·f²´_¦—V—X‘“W ±g©Às¨©]‹™O’“Ts~:ƒI„‡Tv€PVfBcyNŽk¾ü´Öÿ±¸ó–m¸hh’Qzm?ªjU£‹c”£Uˆ¹Nv¢M‡zR©‰ož¡nµžv°¨€ŽwWž„ºƒ‘š`|•`œÂ{Æsˆ°\k”BUu@t‹b¥Í’°ë†} PquDxŠR[„?pzF…`œ—sÄÆÂß‹ªØsž«k§£oš¨n©¬{ž¾yž³h‘Ÿb†`€ŒYr•\z¬w‚ˆ⠘ݠ—Û”–È}‡»v¶m…¢e\{’[~š~½ÜÁâÿ¹Äà’Àu~¤tˆ¨}“­y­Ã˜¸õ¨±õŠ‘Ív¬·z³§i’[~Wœ¦b¤¬n›¸“ÎæššÑzn¢e[“NK†M@…IC‚O[ƒNk{GfŽOp˜@cŒGmŒSjŠXr’gt›K[t>\Z~­Š˜ã ˜çˆ†»qišXl”bg“{˜Â‘²Þq{ª`t–T^s8GS4XnM|›c… UhŽC^ˆAStAUqIYwI[n)FM,YQ+b[,gq9m{CMqMdQGX=>hHUO@[,«ŒT`:Oa6RoA6d7NB@,O'.3!I?CR*YJ.\W3Oa?P]9Ee=Q^:He5HM5PK3HU+FA4OS7…e8M°[nTAQsIScN[h@ZoDKmDU[.Xj,†DŒŸ`‰ZJycYF/‡}:]uk]kFYg:QX@b[0nLbvFLE[g=vw2:\J\5T{9Ju3]f)lŒ;7oA)6%22X=Ga)7S%EO%Hi=FG.hJ+gvETšSPGHY5C_&=T#GQ(Xy5[u5›‡BÏ€^o¾eB„sYarWhxB†„JŒ{SAL;ˆA%ôVWcq²\9XhQI6G8·[€sC¢©\z¸~±”a‘œ`lžX²zE·‡mcteŒ_3icjk?UZ:b\/jsEZuC‹|@×Çtÿ¨…Ùÿÿ—ÿæir_‚PP›_Wy?VQWy4p{>„˜ZngIt‰P}ŒKdšWQ˜T‚N;®œdíÏ”þÿтʙŒŠ^z„_štaµ€]Œc°°`³Á‡·œvÇ~Ò™~ÌÅ¡œÑœ»rÖ£ƒ¯Ád{mFjX1{sSzŒQfŒMf9¬kN»]KmwN¦SC}aUezKepCN\5aT7‹‹]kmPelT¦háÁ˜˜‘[xvUº}Q…‚Tsm?{oB®‰Dè²h«¯~e‰Ob†>x•7©°fŸ¼“p—en†L‰TŒ•Kjv:]u:s~?pzMÊŒe×Ș–ÕŽp‘UeR‚wFšZ{…Qƒ–WŒ]‰ŽT”µdé뺙þ©‰¾_h³SCZ5hY<ÿËqÞÕge\8]uEdŽZo…T…{Nk€D¬ŸsŸ¯{œ›hÛÿ€Ú €ÿ îÆ£ýÞ³’ŠV¢–^¸•cÿëÀñÿµ®ó”…®ešWy E¤ÅuÇðÈÃ|×ÇuÅÔ€€¢Q¨£qÓ䱷㎜®h£¥Z†•OŠ”P¦R‘S…P†oEu@kˆHOn2Yn1^q8DN(TC/eVC“^Q´«{Þ좭õ¥¯Ò—°´|}ƒKyr7r†Ax‚SwrEO™Z¨–^¹¬}½¬ƒºuÊŽs™uׯ‡±“\‰|W­©v޽ci”IcƒF^‹WŒª€²Ò›¹áƒ•­Zz—V”cІTq†Km‘e³Ì†«ç}¥Ït¤Ò‚£Ã‰ÑÃŒÃʣϗÔÓ–¸Û…–·vx°t†³w›Î“ÁúÈÜÿÛàÿÓÄå¡±Ç†Ž¬l{›b‚¨p‡²t—´l„\†g¡¨…¹½‰œ¹u«h§n‡£rˆ«{ž·Éâ—¸Ópޱ[uT“^Í”X§œY‰›b–›c˜©‡¶ã§Àâ–«Ñ” Ð¦šæ¢ ë žê€ÅbWl5[s>n‹K`‘Blœ\¶n–·r™«ZsŠLo€Zƒ‹®Ã¢¾ã¨­è“ŒÅhr†`yŒo–¬¬Å–´`h‰OSb.DV5SiF`‚FqKq—Po™M]‚>Ml:Rt=Uhe}PXrM=qK5R=`?&ep'b~SUh?L[6bP-LP2@`BGO,AW08C,KI$Lj0Tl5do8n{9u†Ka”^]}PqBhŽSgbW[Z:OrA>R19B*G<&YN#Vg2AZ?LO3Vd2g`Apd:PŽDJwKBh;3P=H? NU*Hh9AU3LB+;b-?P-=E)AU'Z[-^Y<_`;RT8Sm1PX3V\3ug;_•H¥w\“tTpcFkgDYtSbk7c—;†FYsQZ\=B>;c5wd)Z™XTN³qFgu_£J:±™l€œi‚MŒeE³˜d´Ú…¦Ë‘“‹cu\œjDÔcc•:UP-XE"cb8NI9QW8SjEQN.`d0`rF‘~=›±l|zPéVÙÑ“™çŒwuD€U5p^2kj>Nq?w=‚§hCu;qd.hwEY}P¢—Svšbž¨oô·…öÿ®œµy©ªW¡¥r´g¢ƒj‹œX«–`ƒyUŒZBƒfL¼¥räï°±œ…¹€_Àí¤®Ü£y–rn`:vTB‰Q>f€H’p1X]?Pk;YM2ehB~g>ŒcOvnX–x]‚`‰R;nQ?ª{U‚nSrgIziC´wQ®®ƒÉ§lw¥iƒ„E†ªK¾°r¡Ï—q•d{†V¥±t¾hl~>i”D€µh©ÁsëÒŠÑ«}¿–k Uu±_Rd;…iJ‘œXŠ¡Zu‰Ehm<¬†Z¿ÅˆÁï ¢Ûy†¶X„‹[䜂ÿ²~ØdDmU:RS/~eP޼¢ƒËІËq†«pfo=Š‹ZÝ씿ÿ–èà¡åʦÿÿùÿå¶‹Q¥¸uÈü¢Êù¦­Ü‹¥¯l§j£±gª­Q¬Æt«¸\¨¡\–¬O„¡M ^¦¤]°¨c­©^¢·et•E€„E“ž\€†@„{;ˆ…D_n/r…?o‹F[}IY~:š•e„´fgoGbnKY|G‹¦që–Íï§“¡e¶XIŠtDdq7‚{Už~e«‡e‡‚`‘¬x¯tᮂÿ›†â x§Žo»«v¶‘sÇ¡vŠI}Ÿ]ªch•OmU}¼|£¿|Ÿžd¹{Ÿ¸g~_˜ƒdaŒ™cŒ¡oª¢u·¹o£Òr‘±n¯f‘‹tª¯–¬ã«Æú®Éç™ÅÙ—¸Í‚‡“Sw{Rž‘–ÝèÆÙó°¥È}{˜iw’Xnˆ[rrˆ©~ˆ¯st£_rƒPyqLx„U}a€©j„®y€½‚´q€«kˆ·g¨OtŸPvšMf‘U†“e•¯s•ºk™¬b‹”j®}˜´t‹©‰¨ÄŸ²è¶·í¯¸ñ§µÒ~|¯HLw2XvMp£Wh¢Zƒ·p‰¼b|Ndfy¬et•_”u‡¸“¯å«¬Óy€•YwŽj}v”¶ž­iv˜Xn‰BFr;[m9Wv5+PQ*lr7\{GHvM0WH+E7-:,D9CR#NX0Nd6Gp7Hj?Cf=LW7Yd0kl0zx5U‚=BrADJ+SO)o6·BRÛsNu¨LJ:PR*_Q0vh3z“Lsž]„†R}…PsmarZHcZ:V^@eF9|N2Tq9^XC]V;nm=BŒMha]{mUM,P_(FN+HT,EY+Q`;aa3owHh^GBkFSVAXB#\x=[p=<ŸT3O>BF €d,W†]UbGLc:QS/dX+HjC@XA4I,;8(:J(;I6eM&W{1If:`F8sx>|†\€eQhW@ÛYAm«q•£[[’[3^H0<"Y9g€;IQ{l3ArT•J,bp;k~IYlPRqCNcPSd2F\.CC+Hp4„z@_ÑodŒJRˆ?In>HV0Ai.4g1H`&^[(IRBII/TN5_t7Q]3W;‡kJpc^‡QSzAtj4‚aG]=8K.*ˆ_,îŸ]‚ÿÐI…j`D.LhEVQ0“P4”¤_¶ÌuÕ¤t‰³„QMQˆV3†iG‘‡]ž¡h¼¤w¯˜t šjX¤qsR3jƒKÛz?ºÿÁZµqWl,o\.PS@EB+^D#F\@QF,kaCb{D‚sDlˆT^lG@`6wR²‚Dj½y?y®§i‘§z¸Ò¦sí«„¦a…’[˜njNa†=‹Qºlb¤Q]:Ž€Rô†«å‡˜¼b‹²aœ‘iÒÆ’Øò­UÀlUjJPh?Ah3²†pæÿ½ÎóÐï—íz›H΢måñ§Õÿ¹ÿÿÌÿٷߟz§™hŨƒ¸´w’„Q«‰d£²n‘Çp‰±Y’µc¼lm‰Irm>ˆ[μ‘Ìß¡ÀgxŠD‡{HwDpe9gw8q†>np7q†@y¥SiD\x9i~>Z}=bq=x‚L¦£d‘ŠK~gL‘ˆf¡Í½ö§¯àŽ…šWpi@lg5lo:ŒbP­y]ªqP„nH¦}cº‰nÅ’xÄ—sœƒd´eºœjœ–^‘}d›–^«sš¶lxšIjPŽ—j˜e’xW˜‰n©·tqNŒ}Rx|Qz€_—‘`Ÿ[…ªY†–Xq…TŽŒuººžêùÊòõ¾ßá›”a{]‚‰Ym~KOk8H`>zl_“q“st’Ql‚PxŽk”—x•œu¢•ƒ»Ä“–Õil”HfƒLqžWržYq–e‡nŠªmŠ­lƒ¦Ul’JiŽO«o›°hiŽVt˜^‹¯c‹ª^„‘[ˆVp‡Vt‰duy•®š¶Ò¶¨â—”¿tz™J_7IiCg}Us’^¶™Äly±e†Ç¦»ï «Ûw‹¿{ƒÄŠÔ²¸æ¡Ÿ³_qƒR{Œ{³¹§™Xs|Xk‚K^|EUw<\wCWs;UtE_€L]xE\‰RfG^nARk@OrEPzdœˆ„°^YzCSoJaoFXlKc†ezªl|«cn™qƒ±q~œQj}R]–g}³zнg€­n¡cj„PfSDƒj?ŠJ˜’i`z`Twb;v`<^M?LR]8Jd'Ha0F]4]^.‹q*}±R«‘gHÉm<|¡@NBаY€°oc©g?‡\NTBDW,\P.pt;hŽMEgQGC2RH:X3JX3Gp1Tc3sk.†H{„m…bqXІQ“TO‚eSJFXM-;q;?]EKV/Hh2Z],5_6F=0BK";T36U38A(E<>[2=A/^A&X7{nE‰žOt jXwbH]=@C1GY%ES)_N+sU+`x>urLn{E_hQNlC5[IHO&Hg/QP5UQ6;“RTT3rr7UXFkNL^4F]1TE0TS+\Z9q\:v`C^_KDfE_G2Zs|a6cb=J]=89$AG%jV.¶}KWÃvRsI8J2QI#y‚Ey“[v£_hŒX}•F†[gˆWc€;°s-’¬aZ…=jd=ƒ†LžwRŠ„^Ÿ•XȰŒÀƒy£iY©{`½Œg–Ê“jjMeK7afC†ƒW‘‰i“„id‰S^4*hP2j[2li=]B/aBbZ?h]>µf@vcG{œnRyQXfBX`?k}KokBQY8\]8€a>¨eYbuD€g;£†]†‹]PP9LM1`Z5fd5\c1r^3xŽRl‡N¬gV¿Œ‰œlÑÔ§´ÿ¶L}DWR0\N2¡‘sÎܬ»Ø¤š§|£fprNV|@ig<…ža­ap…LVƒ;p‰;§„Y¢š_”®c¡¹s‡´k˜ÔÃ׉°ä—Öƒg™Ra|Fb|CËtn®¦pŸ°l¯Ñˆ—Ó|“œXÒ»©¡a½ylÍ~l®½ÃÑŠz±Wo{Fs…ExvCU™Ÿf…­W›¦néÔšÃç”ÅÍ”ÿɹÿü¾Å͉»˜”—d~„IoNfx>x„G}‘Jz€<ŸT¢œV•“E_|7^z8\s:Hk.jfB¡†`—T{…O“–yËá±Áð© »k‹X}tDxv?fc=bL3qI5uU=€bK¤pP­‚m›œm…yVÝÿàŸ®Ó|Áº|»Ùš´SyƒS…ŠQm‰Ih’Hk‹Zw†OgkBnfR°¥y{ŽQˆ€_i‚TskP{wP‡¢Y—Ác‰šW™vªÐ¥ÂÖ°Œk‘vY‹|XgjCegDanAY^2@J$??#AH)EY8goaƒUmz\zŽh{„Vok8ea5w}U Ÿl€¢Ua‹IpšUr¡PjŸRp™]tšb„§jv£NfŒDgR“›kưy«¤bhUv†S‰ŽRiqBal?Tp;QiOj†gvžy~¬† ½ƒŒ·_a>UqW§Y@ˆyYB=aS.YM9YX=bd?i€A¨PËgqâ´†¦Ÿªlm˜o|rm“M„¢or¯vm«`c€dLfE]f>uu3c‚CLlM%J818%WIAt7TV6Kq1Xl4¤n8¤±HWÚŸ?FGJJA'8R(3C.9>%FO!NW%CjC?M6DL'NR*0[24@*HE$FN&3?E AK(X_05p>eo<=…¢ZP«w0eEŒh.siOT\oi@_’TK{@°F'˜–[h³•e;œ›Zpºj¼ƒ>¡¿j—ºh—Ài ƒN¦œSš‘_‘«a›°ƒÚµ~À¼’ÄÆÁàŸ¡®‹ó¬z³ü´­¾€a†d\8rSB`<2]>3YI1dN8u~Qb‡QUi8RX3TT49Z7OL/RgGZ]?C4r›\FŸPKf3{–Fl‚aaŠMVr?’ŠFzžbuŒL\‘N{=u†>ªpCŒ”uŒ“ft–c…T¡~VzQAZT<\D4^B7°…T¨ÑŽp–h^a7iO0GR1Ya6vW]rIbe=Tl?^f4nhBgx8b~AxpGYuEPF(¥XN„lÓÍ™ÓHk7I[/\a=š£~·»¹Â‘ˆŸl‚WŽªw€²oŒ«l˜°n€Um“Gj„KsŠPˆK”Q‹ buŽD‘ƒWååÀ¶åÕá˜ãÿª°Øy°°l¸­l¡˜d¢–c£Ât¬ë„—¯iœŒS´©{‰mŠrB‘wH¯‚\±•eØ×›¯Ö€†£a{œ[‹UwŠLqF`™©€Ä»‹Þ²ˆ¾˜kº‰hê¿£®ò–ÖÏ–k P{}HqB‘Ž[°Ãyƒ®Wt~=‡=ŽIa•FKs/Og+Bm,Yt?v”O†„I“ŽW»¨‰Îóµ²ë‹ŠŒU‚T†‚C`[6eP?^J8sM9cC5ŠQC”gK„jM¤}pÌ—‡ž¯ŠåϘ´Å¬¯t®©m€šLcz>†Px—JtIg‘M‚ˆPrz9`f>‰—gƒ”SbRÄ~p’‡bˆ‘n »|—¿r¡s¯ªˆÉ¯…ŸŠYriFdhN‡{Wt}L[pG]g;BP#/6#-6F!?U+BVCcsMkuO€“cj„9CW'D[/Gf9f…`Ÿµj{¢Fbƒ@c~Lq¢Xu­b}¥hƒ­m‰²btŸOj•M|“b–bŒyO€qMj‹ZƒŽX‹‘Vk’[c–W_‰jw—m…¥vˆ¢eyhŒ¤[dAGh3Ng:YbAjŒeŒ¶}¡ÏÖ‚ˆË…‘ÚŒÐ~q·ƒ‡´›Éš±Þ’ž»ci€MræÆ‹Æ¢Wnƒ^}šWišar j›Ñw—Ëj|¥cƒ•Okm:\qMo‚WkƒOb€OcTl_}’u‰Oa|?Rr=WdFd€h|¥z­x•ªuµ—¥å¥¬ßˆ›Éu| €ƒ¬yŒ«ppft—cu‹b^}MjƒOc‘Uyq`n‡W_ddhbXlWQ]TZM:>^5€T;†„2{WmcY{[KvOJeH9X;OI*UY'CU.iK5^k-RrSšeFm¬K?…”1F[24/3:#=<AHUF&bg*\Ž@ÅeJƒ8S°T‚kYr>Vc@f_=†Ct­d¨“sžÎryÖµª–|±n~i›“^Œ©g~”{v‰\bžXZT`NBZlJR{IAl>6S.,J&>J(aT%?9OaBZe-A&2*98NU$Xs8MxHJk=d~7s@V—Y9cL;9&=<"9N)9K%@P >B%Cc9FU-qv5o‹ISyMF`<—w6V]RgAQs.9U9F>+JO.];&+C7X)[u8EUK]<3UK9;Q:XG!Mr4ct6yrDUlO†|=[›eIi9BV-K©q@qÖ–¦LR›Klw$—w+Œ…]ƒYfTAxR;{dC‡Nˆ™i€¦i…’_å~Mdz{š­f½°f¢°s¬¹lZsXk6ZR0ZU5SL(dK1h@*jR1je7X‘\Mw=T\3Ff?7U,1&@,?6[N)n8R€:}‚:lUZ“\Sh8v‡Eqc6]…HX‹AXAas6tp3™g@‚[’µ„|qRƒ—gb§iZ{Up{T¢ƒ^´º~¥º|n¤n\QaŒHMl:qzHzLt\=ÄWƒ„Vƒ„OJm=w{M•µ˜Ã›{¶Šzº{{š_ªƒZošqwsWahBtiDg}KFR=uhBˆ|bc„VOd8_w>bwGaeAbh?SWa€Mt§g—°{¹ç²|Õ–S¦k[eCVY:a[8§¯tz—Y]ŠRgz>}U£’k‚­{Š•c|…T~›_‘džœÐ}˜Â|ePf|:`ŠC{ŠHzŸWjŠQz‹A”VlIŸžlâÆ‘¬É‚®²jÀÓtà²_ÿ±uÜ®s¹•b¨”p®¬d¾Ð|šX†’O€YauAy0F7]ŠB­_u¢Lj‚Mˆ˜sÊÙžºÝ~zHzjHkwFegGwqF”gK~iLpnGr[E–mTjG—c[Õ~СŽÀ¹™Ì¾„¡`—•hr¥[gˆAqHy”]„žXo…IqtDpqIfyRšlŸÁl‚‹e¸•~ã¿„±Â}§¬p“–]Š‹aˆƒXmnEutV‹‡c— m•¯n…dyTtyWel9476<$?P-KP5I_>]vRT{@Sj>Zi7A_5L_=^jGbzDl†?Wi6Vr>Y€Kx’\t›Tu¡[} gs¢Wp™Uz¬bЦl¥ŸfƒŽU}|Y_lŸ®Š©×´šñ˜Æƒt±dfN[pI_Eh‰\v”RW‚;Eb4R_Mvªv’Ô—°ö¾ÑÿÉÎÿ¼¾ûÁ½è—³qŸr«y¢¸o¥M`Jk˜p¸¹w±ªX€Ÿk…¦e{SnsY…ŸsžÏwްl|ŽMUa;NiVh†bŠ‹W„HhvD_qKmxPd|@\h6Rc6LX;`{b|£_u˜ToŠZx“…¤Ë›¸Ù›¿s‚§t |‹žqˆ”lq˜ds“h€zUoœVO‰oGgavGMRt>@pL@HCO?0OX+;Y:vS8mx0‡xKYRŽjVwkJcJ;R6CK,HN*Bd3_O/I]+[SC­Z3y¶ON—§3Ja33/(9&.1':>QMy[c…/m}]œgF‚~>ret~Wˆƒ`ˆmSŒœXp±z Žv‰¾cq³ˆz”rb“]sb[’wHk‘cmxgw™FjL‰™\{}ZpŠ`U…W7fJ=R4FQ!H\$fU.TŽ4MiWK\EUG4Hn0_S7½^.ÅŠGKíµ.‹³X87WW"C}QK]>Lj9GoTn8s…Ch¡VdŸaj¥ivc¬^Fªc9zC9_4:Q#8Y&:G)6V/FC"4[14?(@3WK3Zl9XtMg€UcŽY@†Q_Z4k_.Yn?nlD‹‹J––[f•qtuEetHapHMoFKXCO[8df>n•N{e“Ápr®sqžjOƒ\]]?ls4f€MjuCwtT¶˜cXÍŽPmXuvGp–ZmhKŽ]AhI:O+Fa)?b87Y8aW,€k>diMpbF\‡Lj‹Ul~@`©cf¡bLŠR=S0GA$lP%Ye0\p8T~CSnB=a:NL&@d5NS @=*U4+`k3fnMgM?OL>HE9bE&aG\‰J}i8Z„UŠ‘JS~\SP(F[)k? }`)©}=s­t[†`mp*wwO€cPhG|iFbFsqE™a@t{PmŒSyeM—uO}€j‘lB“ ]ŠW²sT½¼tWx’Pyl:g[CP…CRR7\Vzd6•€^ovIZyOk|JegBnpAg~Pz•gwŽg¯…—±ËÀš–½’r­j‡—k²||¦p‹¼pUK^BYˆBkyEm‰Ys˜Y^’Us„UŸ¾…Á~€©^{…GfIZx;rO|‘Q}‡Kj…Cj„FtGƒJ™—h‘ŒV—ˆMzE©‡`®Äy£²ož’Y‘J€™P}˜K½‹Oœ«På©ḭmƽÍÚ€´ÚwÕ¬zÿÄ•ž¬lv–FŽJµY’ƒUŒX›…]ª”cÃw_œtT¤‚]…_ŸhR‘pW©—|«¦ƒˆ–[އTrHg@™aL”‹[{Á[q”Ez£`q TL}3^j;[‡Bv…Wh‚Jde4amB ©€¹Þ’¡ÀhŒ{VhuFc_A}_DŠ{TŸ`˜ c…‘N}nGžcV­Z“‚Y³‰`žsQ—[_¦£|£¿ls¢V‹¬t|ª\f…WBW~Q\ŠP]€;eˆJo¢Sx¦^| \xœjœ¶r— YyVŽ~a™‘\ž„_›ž}ŽÊ¥¼äÀÊí©¥ÀvˆIRi9Pd=L_3LQ0TJ?g_HjU\“nˆÀ¢¹ö¾ÜÿÍéÿÖåÿÇË裤ºmh„EPjDb‚MiˆJ_t9avEp’dŒ¦_€“Vv‘X‹¡d€€KclGc‹Y„«s…¡w—œfyXlƒQm}OcmBPa?mi@jlEdqDYj6Pd:IZ9H_=ZkIo‚Rp‹BZv8VrMq‘l“­{•ºdz¢Qr‘Zš[’“c••_vhˆz>]‚RXp`9bP>I?`0*Me-Gj;aA8Ff4B`9VV4oc.pyOk`Z‰`Ny\JfCIU9;R.EM.I^+UZ1A]4ZH;³E'w³GI¡©@IaC<+5R-,D654%{J~[IzcXgQ[pXlDd{O`zNN|M@b=AR.FM$mT)pr5ƒrJfŸT[sIKZ0JM,RC*Xk:Z‰T]ˆV~‡Uµa~›f’±jtǃ[žcSzTSyI`Y:„s:r‰a™‚dW¹wtxNqŽOtVziUƒO@jT@Y2oX(NƒQ0`D?H#MS%=S-CH%_R&Ru6ctB‚~9–§ooÐ’G·†8rUJ[1P~6Pn5Ki.kŠIUx'X[:PtBL]7Kh0iU+avE[oJtf?‚Y8„N1{ŒPzKb:wyNpI9~G3jU?gI;}iAntM}|D{—[­‰Dͪm¶‹b…«sЇYxœakmJNU1}m9sWv\<®‰X^‡^Le4“y5u³_HcE[].{‰Fªb?YvOaT,jp]e4•\=¾¨~ëÉž˜Ç„¿¬z¦Ã‰ŸÃŠ|›j§€€’e”²l]‘UqˆPV‰J`l$‚wLg Y^”]_pC©i@vKlŒxH~P@RG7G..D,;4FT Sf,l_,NˆHHXCNP+NW1;\5@Z7Lc8`p;g†K`bj‚Tq†Xb”ePzdIdQO^5_w@W„GO_DLgeCCP*AX,AT*Hb2Fd1IX8O`5\o@HzB=cN/`54D,WH(WX:y†FT;EN;HO*9N*N3'€y0ƒ±qr±sq¢pl^„Ÿa¡¸o|Ó‚n—yGjJfS;\o5_zTL\?”p?O¦mfrFl{Ey…Pe“aKl@Lc+.`24C'<:'0I*8@?S#;P$eF#bP+Nd6Wc/gu2ˆm7¨¤h­¶~•׳‰Ü¹L°‡JdD‰h=U‡NRgXpFa\?E€VjD,£X9hFvGUiB…`9hoOwcD‹kLŠ~\uZprPh{F{qE£tG‚¢jtjGc[a[7dSW]>`2#}c:¤uyÀkwÐ{”YghAGi@EV-mj'…“JXmHdn8””Ui~eK5ueFrfAcvMULsS/kZ{R?dŒ[m‚LR¸»‚±Ë¡ß©‡À‡J`.]s4Ps5E\'•jA¶­}§Ý€ƒâxŒ S’“_Õ²…ëèšžÆwq“P{~E•RŒ›VކK·°oéæ”éÿž¾ï| Ål¼›mÌÏ™Úÿ¦Óôˆ“¼c©©e˜·Y˜ÃZ¬Ö¾í¦Ùï¨äþʸڛ¶¯–­p¯žt«Ã|‘Ëml²CQŒ4jk?…wH~qJ›§p¿Ü¿Î˜Ék`‘>Xa7d|?Wv7h‚CoIT_7Z\0d€Bo’V¡¹k…U~iU€…cŠ“^yPqY³™yË¸âæ¯Ìù®ÆçžÌçšÊÖ„žŸh™ˆd©©y‹©fs™Mr‡J‘^±qs¡L„FƒŒG‘†X›‘gˆ‰X£¯~œÂ€ÉÌ Å푪´wŸÌ}‘Æouµe}¬f¢±lš¹™¿Ëš¨¿ab}A{†l¿Ó‘çà–çÆ…ÆÌ—­Ô†ƒ¿k~ŸjŽžly™djŒU`…]‚¢qŽ¿x´¸z©Å}“µv‹´ƒŽ±qe‡QuŽo‰©nš[€“LjFj‚FxŸ[}¥f–Ä”¿ë¨´Ô…˜¯v¼£q»›m±•sµÄ•¸Ü¤ºÖˆ‹·qˆšbw—\~–hm†R_xCOm5=Z6DX@j‚t—ÅŒ¤Ô–©Ü˜¯ç¦ÉÿÔâÿ¿Õ페Âtd‰n˜˜d…”Kk‡X}¨o“ jŒTy†Kx…Kq}PpvIvsCk‚AW‚Nh…RvLuGi{JksQ€‡W~7JT,FT6\d;Yi?ZuJ~uBmb3Z`6Pe9agB\o=XqAY~Xw—eŒŽKhu?`ƒM`‡GLm>LfJgy`nCO€OGdMFY>2R=JM1SX.{X7P•ILkdObCa\N38H-a5Cc5?\+QS0Vd3[mU^|;YtOTuV]~YpŠZc„V\“S8ŽSFeLPc?B^5VI2Œf-~°xp¢oPsVhdAy}Gd˜²pDµ—PF/Wa!;M#@IX`"Nf8Oa+cn,ŒS/Ÿ‰F¦¬‰È±ŽÙ³|ÕÃ^­Ž\U?rB\=#SF6^V9\q,`U2zg8®sJÅkUµp]žmTŽŽcubL¦yP}¯{h²ZV‹Y`M+wC+U[3xo>y¢\HqQLU2SC/mI)kpN[‹H]n9kD1aŽUSQ7}Q0ˆ‡N‰oX‡Q;„M7i^peG–kEO/^I)¹‰V¯ý¨®ÑypšZWnHM`D9X/`L!’•DeˆSaE{{A?<.V1#}N3ˆoD–iHa£lv„IŽŽU{®j„§gœ”_ƒ±u«›g½›j¨¿œ¼…’¿‘V”Z…f6sx<°x6ä·ríÅkÇÏ}Ê꘮ãœ{¯tkŠCP`8H@,gK3>P7jc6{{U\†MXd-gAªW†§au˜Py†Pf{Dj{J‘¦ypŒWf‚GpˆPg’`vH|…WMqEcr>V‹=dBb…M`L\‚MHw<“ZˆÄvXy@TzJg|IpˆPuƒYl‰X}”pW•[\cwwN…‚^˜¥{›Ã‰Â½”øÒ“¤Æ€®´~¨ªp«Ð‹·ä–Å׈¾Èsªªiœ²bx U«V“¯T†”F‰…MƒƒRŠ]¡™o¡¶n‡•kŸ¤p™Î}ŠÖp|°n­Ë‹ŸßˆÆoˆ§i™¸u‹¤bbg@sle ˜hw‡PivDZvRsBZ€I^xCE5FU7Kc3Wr3Yq=sqAqƒEa„UhqM[\vnR_‰J?uXB`@MX7=\3CG1B`/W`9]nGi{I>~I'OL./$6.e,WT(F]B]Q5Yd2[n=^rBTn6\pE^pHe‚MdˆE_|@XqAdw=pDN‘HUuEQx7Hh>Pe1zx9x®SOškIoHH‰GOzOXi3U|7N€KTƒ;PFSpBVi?XxK[r7B}GFR5Ja2;\:4=*=B$YF$Xw=VB_fHcnKlqJjzWbzTkR•“V޽~‚Ç‘w¿”i°{p”u`“]GlgK[AL[3_X6wO:¹oTCÌ}RKQO^;KcAM\5Rk/rd0CW7X7`R*©€9­§eƒã¬Vϱ;^DQ4*\29='NMÿmIýeTï„Wµu¡’j„¤{“šW”€Tœ]DŽR6‡Of ;ri3™G(ÈrBÝà…µ{}¡dm—ft¡ch¡^‚„OZ|HˆyFzZµƒ_y˜npzYŠ„X™‰iz”Wvh>†‡Kl™_ž^k‹TUgޤgš½qˆ|O¹Î™žÊƒ}“U†x?¢”h¿á°ÍÿÖ¹ú·•å ¡ÊwwžLfwIš”j¦›sµÀ…ªÃz¡½nš„RÓÕ™ïý©Ÿÿ‘˜»e¹p“ŸY­Ÿy¹ÅŽ}µT§O°³x¤­r¼šqëŠÌ昩àw¢×p ®gsQuLuqHci8h^g8Gp-l`7dvA_€Dr‰O…ŽPf8Yu.šœNÈÅk€ˆM‰n?xiNm;Om?Uxb~¡„‰¸ƒ—Å¢Û•Íef¡U\PYŠI]‚NUzFM{RU†ji™sv¢ej‡FTf8Fk;5jGFQ=TH.^[2ZiAimP‚v\Yx_d~jL†Ha_DV_>amA<{EdB=LB1wO8pb5NxQubOqEpšhJ€Ld\ƒP4Œ|0O­wOc~eTCT_6IoKScEQfESpM^vCg=Tq?MqIK^:Z[5PX5SV.R^0I_5he;}‚Fh—W]_S^LVK8[X5Tf9OR3yQ7vRN‚QStPK‚CVkA<;Z]9ŠOz¥ecŽjVjDQ_B0r>074*@&>,K<1[2=>)>Q#>O(KT&[a'Y|:ZxEQw=[j4mw9e~MKjEWS8Fe5Rg6@p6N`1gf1uv8^IWkAg<‡FQ¸€OŒuOi8bX-sp7o„FnOe©NR XM˜f>iBHL/RM&4W34@*EE']_1a‚I`O`^A_cG`[JJUCEG3YQ1ff4g8›ˆPȬj¹ð—ž¹ˆž³†ƒÑ©`µ›ToX•gRpa_J@[d4?iBUF9]u:_wAPkDkh6I”Y?kMba3^y?ƒwMÃs?©ªyvϨbÉ£L•€GeO‚X=R8HQ'~a0y£_ejOJ=1eD2e€SweWˆTŸœfcft~7cuGe`8}‡Y§bYŸnWU2`V(iW.‰M4‡F3jY>`e>aDlŒIƒƒAqyOSfDh[=tJ¾•kÿ§ˆºŒ…wfP|^?K6‡¦ga´hjq<^yQyjB^‹XlrK`€H^w8pwCœ}Nmf_ŸMÑ쇖ë­n‘RSM0NF*W\+9d-LG­‡Hk¸qeX’Ÿa£ª‰z}\tXX7GP0wa>{rZ`K9S@1PuEG©•Uš‚\·Ôˆ¥î«žä²«é­žÜš¯s¢Á}“¿~¹“Z‘†c”zRˆuK~iEfuFZA+‚V7—¬nŠŠZkn@L[2km<ƒ~Pr¬my~USlC;O(6G"=W.=Y+@V/A\9X\.>b1‰„J¾jczLD]243HW-jlAƒfƒ‘i³©± zz‡[g|J~{OeŽQWj2f|G[}>gq<\=mJ¢¤s¤¶u}ŸW¹½€—äŠpTonL†lRÊÂ¥Çì·Àï¾°÷¹šÑ„¡£j·«‹±Ã‚Ϧb² e¬še’“`\~>«j©¸lË˺ÿ®£à’}¯V”uP¿™j¡ jl£K€£N˜ª\¨†iñ°–Öû ­W¡yT­{f®j¤k‡†UŒzZƒX†qKTZ?kRf Lj@iyAx‚I„Um‚N[v6]}7t”=–“J¥pR‘„`t…Yƒ„c›¶~¢ÞŽÕyj™Y†P€–Yx¡Zrªb{©X‡¬M‹£N†™Ww©Vl©^x¤a~¢]‹ƒaŠ™bg~<`^Y{7\|;YFrwJvJewS^{Zk|Pjn=OU=PfXxŠRnKZtERpIZyZ‰{³³Œ¦Ï¡Áð¡Äí›Æt„·pmœZiŒ[p˜atœgu˜ivžxz©mlRJf/\N7Mo@<_JCI6SF+]]3_XxaB†ƒ;L‰ZYTSbm?csDyaEBU:OI=TW0ap@{{Py‚Q„qobaSmXbL¦o/z§nn{†Zx`SgNmmC{ŠIgš^ZŒ`ZVJp@G\DT"C]*@V&RW&Ug-Vu?RgDmr;_ŒQ@`H=P0IM#Lb'Rj0Gi;DV1;Q3UQ-Zp1E€LKc9ˆ[0ƒšBG¾¥5jgAW-@j)KQ4YT,e3ŒJ^»h9’Ž7YK1XG.jq0A%IN*EW+UP/]q:åvBuùs{y…RD„_N„aN¹ˆ^ž¿‰qͶj¹…^ |SŸ`S‚N[uEryATi5„#–RE˜s`ƒ§k¾“YÁ„s¤lQxWPn@ey5Xn:qvKL…P?A0HNkh8oo6Gp@]Z2k…;vpMtxOv‘o‹„@kžpo˜uÈ™Y¸¦yeRC56c=&]D5vbzƒHfŽLhf?eyQlgR‚\=pgN[C9dN7_`KqgB¡²gfÏ‹buJf];”pLy”lyˆ\i˜`fŽMƒp>q}O~pIÚˆFâó›‹÷·‰WOtXX~MW€MEf/]^7ÅOgŸf‚~Jû½m½¸s‚ÈšhhO©~X­®s¸xpjL_‰Qn{>bj=frA`yGŒŠTv¡je„HXaBn‘M´{M…qN^i5£Œ[ºÿÒ¡²‡Ÿ¸urŸk£™aÿ¯†ßÞ°³Å‰½Å’ÆÐ“Òט›»~v…Tƒ‘^À‰douRyq>hyL`‡QœU¡¦m]IlqFMk±i­’a„§Ns”MŒL„›Ry¥Lvž=©®Nø°‚èÌ‚·²cŸZŠUyyJµ{iá¡âŸ‹Ïµ‰ºžw›‹e’Šl³»|³Âu‰†W~„Py—MfwDorCh~FŒMŽŠN{Ivs@€h@“pJš‡Wš]¹´‹íÿÊÏÿ¥u[–¹Œ©÷£›Þˆ™ÖˆËsŠÈj{Èk¯u£¢s›”i‘†b‡šj”¢iu”FZ`@luHk†bƒ²”’ÓŒh§XLl7YM:laFy†fz^}€Ul QRˆB^vH‘žp™Às…¬l™^}‘iž¶–´â§´ï¶îÿÛÿÿýûÿè¼ÿÒëÿÛôÿ¿äÿ˜Ãã}ÃÆz½Ñ~ž¾ai…Ib|R€šr•­x¬ª‰½À’½Å‡¹ªs¨—Yj|9Xj;_Ln•Hp†;cpA{…[”»u•Áv˜·`‡’RvKyO”|U‡ŽWu>Hm&B_(`q5Vw6IkOiˆ]|¯c‰¬m™´„´»nŽ…A_l5Qg=czPq‡M`u?^r:c~Tw’b‹–g’•]‹ŠOuwPw†[v‰M\rIj†Pe‰L[IbzMi€ct’meX^tK\d7@Q07L9HZ=UcCUiRX{OXwFS~\q‰uŸ¯‰»Ü–½Ò‡¢¿|”·c|ŽRbsCd{IbuJbhYv{h€n…¡Y[{8aC/f\2LbC?CTT7ˆe0ŽŠ=…˜ea‹lXrh_KKIC1„=0“p(w£_”cubwZah[dkKlƒJd„Sh„OWzKkX;ck9WwIfpEGy=H`=H\)HX)U[-g^)NiA`dKVk2UQ<_Q3Xo;SgE€jBd”NZoVXYF`XDqu=Œ›`¬£k‹¸‡d¥…5oV?71\<^Z.Q_46uQ=7?J@)SR4Ms6EcO>U/AL+\H J],VY'Mp2ubC‹~=FŸgKZSR^)Ib.Tf:Is;C^?Ra]ƒBVŠWwfB¥z3Z¸qC…’IZ@Kf66gA1?/CBS])†S+BžP7SVAI%?K8M+Q`4=sB9X,6O+HD(ZW)~g5b@´¤\Ózì©r½Žw}>p¡iBq[9OGH%Qb%qt=Z‰;m†Lf›VQ‰HsŠF[©U‘?½nm˜gotKP|KGj;W]/\R&IM2€K.Š p¸€gn[tMhf7¥E§¶tgŒjZYD…Gk†[€˜Ip›lB/uR;º_=‡W_L8wi<\l3st>ŽMƒTbxYV\D^L7psSŒ~I}m—t¢½ˆŽ×‰e˜sSoC†T9}ƒ_q—dvSa˜Tc–Mš­`›ä›½õ¨çñ©¯ÿÍŽÍ¥ŠÌ–¹‹e»…Zy¬Qÿ—a®¢…°c¦–az›d€K\ƒKnu6ˆqB“’fh|cï—ZÑ•}—W®«r˜¹vx|N]_2k^5ý£u¿É¥…Š_ £f›©qwŸq]T„^?¢£k©ê—”Ôzœ i~fm•a›˜\œŽV‰wT©—]³£e·œn´£rŽŸft€LxxCp€Hdƒ\€›_‡«l¤£t´Ê¬»‹¬ª„³¥|t‡V]‘U`{LTm@Qp?˜˜^T\?E#Ig5BZ-NO(]r>C].gU3de8~K/suBk‹Pu†J^t@I_*Z{A…™U’®lŽ£Y|“Y©¸qŠÄ~ŽX¥h§Î”™tª›p›fˆUj^9Qf8…|O—ºy¥·w¬_‚~M’ˆ^ÕÕ’ÏÞ‰˜Êkq¼Vd¤FQt2EQ+seLi“HzžS¤c¨Z‰™Y{ŠHk|Eƒ›i˜À|ŒÐrt<•kJª€^ªš{¾ä–¾¸wäŽuÿ—s÷ƒnÑ_Ÿk@lU8eGŒ‚Nw€N|JwƒMpzBeh:ii7…w>mªRgfMrfGd|Tt•g¡ÎŠ›ÜƒÑÃÖºq ªv¹Ý°àÿ¹Æú¥ªïŽ®ášºôŸªç‰“·gš§l‰aŽ~Q|dO–‰c”Sr~U€™_ˆ¥ošº‹¦Ì†z®eh˜TP|?LO3`P=vxNjM§Ws©`]Sg†c˜°ƒŽ²t†¡k“£x˜«Ë¸ÍÈ¢ÕàµçÿÌíÿåïÿÕìø£ÇÏœ¨Zv|:KV/bfGv~Md~HhQpŸ[rŸOV~9Oa2_U4^V6WX5SZ9hrC|ŒLwŽGg‰=\t5UeKŠŠ~£»u‰¨T„…UuwSkhLeRŒ„SˆPwz:Gi,Ol7e†Ow§gŒ´cxžNfQvYŠ„JWS.JZ7KeE\tMj{?Wl0Ij?Xc‘°~ˆ»eqŠPlzGnoIˆy\ƒ‡Wp~Q~‡^ƒ–Z–dpiq¢‚’ÅŸ“Еr¼…f©|X–iJ€\GxTHjMOlQcoQ\hD]w`p¥qhžix‡a’•`ˆ–b…’UiETp@Vz?Rp@C`1@C5?GES\P]aA;S9FF4KR5CN3EG+\F/dE1[O8LGAYH>Yb=…o<œGeƒfCvc@dH[F7LH.b^2|\4fJnuZVUY-GA/+-Z1²Q f‘9ImS_BOU7XT4Zn=\i>F\AFG4pF-€\-]fEhxQVk=IwEMh6In/Rb7Xh:DnRV]@Q^0aU2e_6^rI~€Q…ŒLWš[SdRA^;fI1„x1„jtŒugo[AiK*J74H.K8EN'vQ.F‰9PssLf@OX?]Y.8~K/V@J@)VN@a*Q\/YsW¦\Xu[Mk-Oe4^xŠ<On;AZ97Y6MH$Ib*Lc@NW?KI6Yb6Zv@^X9AiFZS2do2Tb9TeDYxLe~PVNkeMt~?`‰bUˆZlG€Hx}GQ•Tjo?s‡DQ…GIaD\k-/U1.0$O+Pb$Yj5NxKc‡OMyBKi5VY/}v=Œ¢_¾©noÄŠŠ™~i¬pL–lQ…>Xz@f€GeˆFz‰C}Q’™X·ÓošÏ€r§iå‚Nø™YXmrL`FEa6B_$@O&IU%M_2rt:«i_»|TWFTk4gtB¶ˆH¡¾q{‡gXRE½L2Àuÿ“Vƒÿ¾Z‚rDS6e0 L1#S4%aC*_uBtl5_eF{^>¤?ŸUD|€c’“cr»o¬Oº}\ƒt³¬tà’dµjx±bt§kp•[ƒžQ™Èv¤¦i®„X—ˆYI³ŠR§×”Š¡|¥¤h›½€pÀx’†H©­v‘|aa†WdvCHzAnj5•rA·¢t|Œmz_D†Tmc;_‡L]x=‚sI˜‡X€vM°qƒ²w|˜C¨ ]’»‡„}Wi{Uq}MÒf=…^Fu]”b‚}_d]Ai¢_l‰NÄ슺üœ‰Ëc›šS¢—h¥‹`—‰Oš“U†ŠN¥›k|‘qˆy[¤‰fžgŠ–jwWnsHƒM¨t}®w‹¼t³ÈuÅ­w¤«u‹¥qygpsFn}MtVUT™Ÿmi¶?G*<>!8P,+>SP,Xx7W[6ra:erKfƒJks<\tuL—‰JoŠD^q8q}A¦­dšb©y±ŠÂ©n¥•Z‡HziIkZ¿‹„ÉÜ¡À⛺ӊ©È{¡ªr«x«šq—ˆ`k¥œm€}TxsL…}aŠ _‡¢\ˆ¸mv¦Wi}Nˆ]wœQq”V€©e‡X[sSdYt¥L„Æ^ˆÒf‚«ZmŽZ‹§r‡›kzs_œ…u̬’­Ÿx£‡wÅ£˜ØÕ®äê¬Â΋™ eŽ¢hlyIMN/CL4LdF_|K`†QgVy•Xq•MssThˆRLi>Y`@Z^@j\:`bB|†On”Ik‘Hi‚>_\>rqTˆ‹Sv{CaaL~mU§|V‚sP€qUš‰c–Se5guFvšaЍk”˜UvyBd…RtƒYue;hX3QY1K_@dtCar6^l8fLz‰`¢®zÌÃi†œIhwFrpE€uJxGjcBcaEnnPhs[r€csb‹ŒŽ¸§œÆ·¦ÔÕ·Ñ󱁾¤®Þ~À~g¬tZšaQ…PQ‹nŽº|ŸÄ``>MvBPxMc~Rl‚Qa†Kg…Ib€CRr8?T2?[@IhALh3M5>H5HB*KR.TC0OC-XM;UQ>PM@H\7tU8K{6P\rVJofB:iN;SCDa=]Z7dh6@kQ;4G&=,0.,E=$\I!b_/Z]:R]:EV6\Y3Th6IT6>A,F=*_[*Tq1S]B^^;[U4OQ;^k@S4XiBWe=Hr^JcJH_1YW4ge6~„GvS^nYGwP=X=@L1gM*u€?X—e>z]=S.5O.a|RShJ£nAdVa€ht}7lHp}SD‚_>K>BL)FQ);O':K$>N"`T N`*?MxK3t…N2KU(Eg?ER8XY9Fu97k94Y+7FR<$;I(TK/?p2IZ.GP*PU6QVLZT6lyA_zVZg7EnNNV4[f/\N-cf:j’al“em`b”eo{Vu–V†¡YpŸ]KtJm]6R‰>KmC`](Fc-Of9Cc,EN)8_@BI/P]/…t<¨K]§‡nHb‘Qf–Xo›Zj—cnŠLoˆUih€w@s‘Lf¤fSt_J]AJ_5di0~‹C™ºdÅ¢]{ŠWV_EpS+gX&HD;]=Gn7SQ1CƒDr–?w‹@ly6lv>†Qƒ”VnDkŠEŠQ„›Ojt4hh=Li(Qh3rR™”rŽ f‰kB…^4gY5ÀwnÍÏ¡À×™ºÍ‘£Ø…›_™_Žºh‡šJ›€B|ˆCvpBjg7td;Ž‚Gо\¾SiŠG‘‹d¬…鬒窔|Gzd@ke:TE/P?’q[ª‹l˜~^Ÿt\…ˆ_ž€f°¡{žl§nT‘zZ¤j“‚]€ƒZ—bšµm’Åu•Ây„¼b^™BPy4[W7]dEw™Xiƒ@gY3„@{Kž¤Y‡£Ob€=[l5h}Cp{IR\Gkb^Œ„»†‚ª”„§”‚·•}«zš¥r€™f‹§tw¥[Th8SXAayaqšg}£b€¢a¦Xg“FOd5sQL‚gFpa=j`@mbAokDszK„‡LzŒGh‰HfzNitGfh=hhQz†b]qyP‡oTztJ‰zXž~Hwz=i~V•Ÿj”¡_srFgjEl‡P‚‰QkvGZxBTm9Jf;UqErJbN{R‚ŒR•[¡·rŸÄh€³ft“\u{DmkA_b?ceC^dF^nMcyNv|Sp…`~™b{–\†`šŽbœ•q ~¥¦¼µ¶Æˆ¤Íuйy‚ÆŒžÉo€¤G]}=Yp=Tr>WuG`vC_yAXvATm@Pm;RoE`OguBL^58ZC>F9QF/YN/SK0_J0HX;BTI>R<>X8^N1\7EœU7l`KACjE,Mh;NjOGV?8A515,Z:%IN"GL8M4-BD'HM.``'R[*Id1K_2>N8"[N#]|3ll:EgD=T;KK.VV*iw^c:`€MYq\rn@XƒXKtME`+IL,zd4wR`}dq^Mm‡O¢aošNehBop7_s^^bft?e{;s@J„Q`k8vz@’NŠÀo?ؘHkIx~1ž«Ns†TDT7OW-HK(2>#aII]-UE1k[,©oEdaNis@ti<‡¢j·ƒ‚‰pbqMXwJ”I•_¡R^”_CZ@UwDtuF~ Wcœe‘fDg¢rpRIvC+GB4]1}6+bK=€F©U—±y{«ƒx˜^’K€½gc’WP]=`Z/[Z6 \1Âзªx‹ÍŽ™·mt­te™VsŽU‘¡c“°lм~oœ]¤–d{­‰‚ŸbŠÁrUªp\r/’W‘ySñ¬i»¾{ÓŠa”lMcP<ªbM¹‰r|…_~ƒMŒ˜_”§sl¯v…>’f–•enŸhxo?¶„lbâŽjØ yÁ“lÍ¡mš´wq™`NzJ4J/G@'aO8•mH´·}ñî…¡ÿ­‘ŒVn®mV–@zƒ;k `dk8rd>tqMcŒU}R_­—d“ ^lp?~€P˜‹XyˆO‚€KoyFep8|qA‡ƒP`oH`nCkoJk‚YPuKMg9‘†Sw®ogŽYq’WsŽZ—da„K\vJˆwL}œQ¤{H‚uAz€Nl†VyxDfj>r^E—]g¢Xr—P˜¦gž°qVz‘U™¥\—‰X¯œv§½…®Ì‹¾Í’À礶͑xÑspŽT{ž`–Ìwz­JxŽH{‚Dè®cÌÙk£´Ur™;V`0ZT+[m5z’L}ˆGŽS]B_jCXCj†Y‹™qŒ‚R{mDZo:_d:qy@GT/ŒXH®¢w¬ÌŠ¿s™°mŸº^¨ŒXzNmj=|A€j=dkBw‹Wˆ¤`ª¸†±ÿ¦›ý~’¾k¸›_©‰\“’Xac5>O5Nd>jƒ_q”k¦º’ÎЗ ÎŒ•Å|™ªf‘ŒS—‰Y¡sZfRuwQ…•fާzzµsz«i‡®m~˜^‚—b•ªg‡­de¬L=i.78-b_C„‘S_‚Ci‰=k˜FZ‚@RoCWvPPGZ†Ke–]‚¢mŽ ƒº¼žÅԠέžÅœ|’nP‚{_~¨j‹Â‚¢á¡ºî›–Ù{b–Qq‹f‰¨¯‰±qy§[q™Q\†FPa5Va9Yg;fpNw~Yn‹Ji‡Gr…NyZ†_…Row=Yc@bjR˜˜nœªb…›Ht@sˆ>hƒFxŠUjƒO`}GtwO}K›zM‰€HoŠSq‘]w g al•[b•Wd l{§nެs­j¡Wc’a¬w¦Ò•µñ ªÛxˆ¡UrtEajF\nKanIfxJbsHesJfnLwwRp|GVn@P\9UV;rnCz€FeoH_lJl^Ktre¢}¦Àp‚¤Ibz5Jo7Bi2He0E[+I[4Ke1Ic/Ij2Fe8KqFUjGYQ-HZBO?>KZ8?Q7bL4lR/YO6i\:^kBPcEMdAlSFbgIQ˜bDYNQZ;FY54T=%L;%%"J(HN3>+8',I E7>I&TK'k`%eY.P[D;YGE>:DH+dL+Ys8[mE?a7GU1[W)Xs:NGQ`/Vb5gR.PRTlWX\+ku;_|MC]LFC6HC&CX*OM.ƒd3‘±Pg­rPc^CV;JX8E`.=^1@R,^Q1QS.CH4nM/¾k2Å‘O{¢qtpq•W\¨vo~bT‚NWgdœP]x[oh:exPNxN[s/fpMVuHQvPSzF…ŽA~”ZUŽVNvXHgHk^>buIYhLct:GƒL=c6WQ#O3F]+_a9Ub7Uq>Qi>Ld=ps5ŽƒAb£hNsSUW6Qb=Uh0du2[{@Tu@€Y9”^0’wE‹M¥tn»rp‘K\BMfeP%p[/kfAfN1vG.fp?€‘P•°oh˜yh[H„j9”ºtާq„{V¼­ihˆ\mPn¡erZqWJ{[h7&»wEFµ™aE5OR1TQ7]gD‰Zn®}‘ŽT¹™cÄ‘wwuYl@Š“Re¤ehpD;P2?>i6‹ŽOf[}’KIi„Bss0ug>nQ¯¨jªÕ”‹â’ÄÓ‚¦Ý¡”ÁvŸf[Uxw0z~@„–\àÈ{ŒÃ“xƒXnyF}nMwsWŸtR‡i‰Žh’Œeª“h€´~ƒŒF†ŸS€š_i‰N¢’W¸zW³|PÛ‰e¾•Õ¦~鼃ÕÈŽœÚ›ÅhšpswUqrF¨wSǪÈý–óû˜«ÿ¢µó‘‘â£Ô‚´ÿ«o a‚^=¤eG}gJˆdN„Œke‰E`uB\|RˆxUrW„|Q›šhlœ^dx<†xLvPs~P†T|Ž`gqCvY;nnJu‰Pr€MaU9t]8k[4rY>VLozEoqA‹sDœ•\sr<•ƒLyš\]Y8eL-iV7p€H§]Ž·l…¯cމShƒ@¥…P¥µ„Šd·’j¾«x¯ßž—좟ߋ¾vœ®aˆ£]«¥Y²£a°\k~6mq>¬‚MÜ…J¼h,{}:e~Fx‹\i–DŒ…L¥Ÿr–¦c¬˜o°¥ Éˆ¹¶s‘‚SwlFbi?Ya8bzCrk>„`‚µq—ªiª»p¦Ì~¶Ñ‚¢ ]“vD‘kD†cDzb@…|I›‰a«•f©uJsF¤}[˜~YŽ„\§™g•’m¤¥s—º{šµuªª†Ã€ÊÕ‹ÖÜŽ¾¿m’ZE±][±|_†€O~ŠKwqF|WE‡iJˆ—h¢©‹Àޏs~±][‚H[s?{“\еxšÂ{ˆÆd]Es‰Vs`’ªltµh|±fo±b[Tm‡Y‹ž`‡¢qµ„µìœ³ù«Èÿ¶ÆÐ¨ÑŸƒ²y[~]BdWN•¤€ŸÖž¼ë±½ò±­Ù…‘©TuY˜n‹¬‰•®‚Фis™Z}šWZ„GQpDUhQv†U~‡V{[{”Ll‡]‘’s¦œ\y‡Cgd=_eIfs–¿—•Çe_4_z1\|5fŒWŒ¤o¡dE\p:^d4][2`^6gnQœm‹»r…¬i…£gˆªq±q…¯€‰Àˆ‰Ã’Öš‹Ö†Î†›ÏŽÀà›º×Œ­^dpF^bIksNarIaxF_h>Ub<=I(7<9LY@[lAGh54T--G&7A)EF-SJ1DO+@U3Ka<`W<_P,GU/Ti:Zq-Jl';\ 5S':[(?\1Ac5KqERxO_ŠRGT)OJ3uH47]??>>9A3/A/=@)UD&Eb'Sa=XfB`w?>o•JX…_CqTEaG=Y9)W;(5(42%:0%&2.;I=I%SI']]+_J1^I;G]FDOALM.dV,K=BaAFL5S[(]c/Uw?JwDPf.Ki7aK1DzOJfNl]'qy;QmGHbKES;BT,KO6ai3—‚F€²VO„oBMWOH'Km8R_ED^9_F5\I5KV?Sf?Sd>]`Fdj>yfA¨kA‘Q{µ„SŽ„BOIEN+RZ)`_.ov,›r4|ŽDMbKqIHh4QX(Et6@w@AT=:Z1/E-/;-.0)::9\CVp3\kJg€FGˆ?;iR:]8fR,hb3Wn@D|CFg;[T3^vCLrPVrC>R7XB*cc-F–RMU9Q[6Y_=‹q=q¿nid[tQNiG[f:v„cO2qU7…nIvvE‰TvzG^U7UD'Z@)_F.xU@vKœsVªŽgís¥–j¥‰cžsR„X=‰P<Œ_Fe|AB^7UN‚ƒ]‡˜f€‰\Œ›]}©_d”P]„QjKšc´qš»m~œX•bo˜Sq‡MuŠQo[u—[n„KCP(>-&b94t[Mš”rÁ朴ی•Ži™a]šn[reL[Z6OQA{h±¢»·…–©[gg3LO9qr]†—t}œu€Xs–\}¢fwdp”\l\y‹ZzsSxNl|FoqG|vO{eMslG`g@_od|Œ­Ë¦¸ÀkuŽ3Z†9\€Lx«t›Ø• àz}“MtlBje:YX0QY6ZfX‡›v¡Çp|¶hn–Znš]tœg€žn„°~œÄ”§Ñ°»è®±Ü™·w˜±…£¿Š¢Áru’LVbG]i@^oBXrBHjKXqQTp=9J3FUCVuJ\rJVq?J_,0F$8B+NT3P]BOj8K\.a.F_,>b*:W$7V*VoGZvECW0iN4GM3?H:>;60C,J@.BS,\I/^W/TqBegA^Q=_i>c\AIvDQTJJc>?gD(XD&)*4)<9,J,:A*RO)^c'Yb:W^GhDeT:vQ5Ph:;mBER;[Y'Ie+N\:Oi9Zh+Dh1aK1Pp8T_LZb'Ci;MD4QL3Wm>GrCbkK?~ŽP€‚UO‚^HYRXJ1I\3AN;CK0P90ST.rjCPnEXKF\T6Wn>Qj:gp>xEn•K;‘|2?>K=Uj#Py-[n3dz;jtFT.MX.HT*_@$jo;}ˆKy‰bކWfœiFXNO>mW(J™E@hLGW5OW=–e6c¹bnqOjyCewO{{G¡“Fr•o`rNq|<_‰COsWPl;eh2[…M_sPmiHZ_Clj8L‡qJ`1Ui1Zl-Wm:_}CM[@zMT`Ixk@h”Nc{R[vOy‚KL’aBkNKh9En0Cg"[_Qr8?gJFO$}J.U€S‰ET¡hUi<=z4:b/KJ(SN*uR,Qo:Lf1]h0S^9|j7zyH{«[x¢`€§gu§o`oEfm2v¦Tm†Q• Wƒ¯v\¿…\‹_m„RWucc9`Y:_gGhlIyVy„\Á¤‘ñÆ¡­¤jœ§l„ŠRg^:geDXgCrTDmdKq{Q‰‡]”d©_w€Id^A{|]’šiŽ—]‰™\€™PbvCf‡K`€AfvIqOqQdˆPg€Me|;Uy;Ui;xy^·…ŠÀsQ{?*6"'6)3I9Z]V›¦˜Îü©‹î˜rÀ’Ï‹Œ¥`oo9G^-6P&@F2_ZK{ŒUAe$:E&IL8tbW‰Šav—Vn˜P‚Ÿi‹œp§p©…¬pv‘\tƒNi~JkwM}‡V“cŠUxY|Ÿzªtœ lš¨Z{ˆ=`{L|™~¢ÖžÂô§ÎÕ¨¡XuCrj:€e8Y]>VmUo˜j”Å¢Ö”ßo¹fo¢\k fv›dx—mª¤Æ“¯Ä‚Œ§fz˜nˆ¬‰§Æ… QcmKis?QhFXlPf‡jwŸo{’JO^3BTHYsZ[{Q[xFOi77X,)G,;C9MZAUl?Sa/]P"HJ"1G'E^5P~EK~CCo5E_,:H)DM-GQ%8G)?U7Ol9HP.bN4GQ1EE3IB0=A4UF.\Q1oM8Qc9PSAMe@]aBF_=bK?dX;mPh€VBt_)RP>05[3!ST,Y[>NhBaT=oM;cW9VREMI>bO7R[6pS9h]?s_BQ_AWU?M[8CL9L`4Ae,FS,J`.UY'>[-TQ1A_'F]8If0Hd1Ga4[[9]Š>clM‚uCgŒK]sVccjk@cŠIE„Ti0?W ef0K†TBh?gI,R^5|o.I›QDuOSa2H€>Hq:BrBGnm“IIzLIL+YR)|ƒ>›Çu¢Ü‚‹£pvaFt|@iYK£‹@gRWd@ŠcB§kUÃ|ÿјËÔ½FaDOh*Wa-wo6ª†FµÄ˜ÈŠ€‹bx†QmzI|rQ’uLlqLn†IŠ„M®ŒZj•]†~=­“L¼Ÿfª–r«‹dŸŠf‚tTziEWK0J6K<(UG'}[.¦s5ήYÔʉœ·~Nˆ_6àžpÑÿ½ßÿ°îÿÉúÿÿÂÿÀ¿yhqAwiC©®}µÎ‡”µq‰¦o£|Кt„ºz¬sx¨qpµsjªr…©mu…SmoCYN,iS>•_²¤q†¬nQl5hu5uC³}‰Áxxˆ`se=ka7ll9ioAl€G˜£d–°|Æ×¦Ç³‹ÄŠr£y¦j…¬bl”U}T}‰K€P`pB‡ŽMq©Sš„Dñ¤nǶo„ŽMc•T¯u°ö¢}µqb€F‰IzJ…zE×­{ÿ°bŽZ¦_“Âk’·UsšN†{VÕ¹†¾Ö˜§lv˜Um‰XxŽ_‹ƒMŒ—e„•^º¨o Àtœ„U¡‘i®¬j²ÆÃq]vAvg}¿€ŒÈ~²á‡ÐÑ}ÐÒ…Š¦l€‘_ˆP‰~S‡|QŒxX†‘eˆ~^ƒ€Z„`œ©{ØÈžÿÏ¿²sÁh®~]‹ˆNy[B|gIv~Rƒ‹[‡]†‹^miJŠ`ƒ¨cw•X‘^~“WˆˆX„–UsˆKeoFewGUo4;B$PP+X]5foB|ƒUŠŒPWs.G[)>R(XK?jfI`b;SW8]ZOzŽw„‡’Ù–´Ý­Ûõ¾ÙÿËËÿ³£Ëki†HUy;Aa)1>!14-jeXjœSKBG€BI‹HRA`j:n}@n‹GtM—€d r–£z¤xz˜YpŠTp‹UvŽW—UŽU„`Œj…¡axšUyžQn‰DcqPˆhŸ±r–‹U‰dG‘aQ¡oGrX:haKyu\pbxªg‡º€ªØ©¸â•žÂsx¤kxhw‰T_yRj‚j‡ rŒŸdv–Uo„f¤vŸ¸lŠ–P^vO`ŽVd—f_Šbfm©tzž_Xs^BLc>?T+5M#9L%W*K\=FTAAQ3TL3HJ87;@C9:IH1|Q4wi>irJV`UT`RL]I^TBoP:>hG*~N(vcF[RMj\XIDfN8bND]TFiPAZSB\TC^O7rd?€dHR…OQfOOc8Cf:JVm+@E1?J(4O36N2JJ&‰c-†9dÞ„iŽ‚t†GX‡RQhJaT6fU3IR2hV6r”Og€ZA‚M>VBPY3J]0`U6W\7pd?ro7voGc“i]‚Oc…MsUpƒJO“U`gM{mEv€X“™`žƒVf{XT[CVu;lf7MlHMSF[j2UjzN5c>AL(UQ+eq6L˜HA\5JM(dJ"SˆFaiFY9Gm9[w/f“M]‚\[Hj‰Tk|Gug<t@žYÑ€d®sTzLKj.qz=€£P|˜pz¥ljˆ]dcAWHwaEp¨lx_Vë|@±dÿW8š¿œk›l¤¤a|¡k`gE–m?ëzHÖᕤ¦oqrPjŒQ\…\Z\:JU9oI4˜™b‡£|xŠN†¡]~¢_{¹gŒÄqUÅgRsAd…;¨¬S”Ãp]mN>\/H7%X`-¡l;ë£|¾ìÔzûу±{|°wؾtÙ®ŒRn]Mz?cy9d…WUbGˆƒ=§½n­›r´‡`•³~—’]¡–j•¼‰}±€‘œ_­­~©œfn Zc{:‰„C¡d´¯y¯Ëˆ•°ok£\Y…GJ‚NL{Y]‚Nc§\t¤XcœLf~I]k:Rc1SoBb€M{J¶~EÃÁ‚òÿ ÿÿضÿÒ_žgVf2zf2Å’]“‹Nu„A¬zB„U“¡`~ªr— f¬¹ÆË˜ÉÖ´¯ç¬‘»xd‰JKf4HZ+‘{=¥ªpjŒ\Ph8i~>bœNnh8lL1„I/oU6q|K€‘Rž[„—U¯Œ[Üpãd„qLgb:‹kD g‹´lsUr•Yg™PnPb‡LƒŒJ˜£\¢²n¯XÜ£\—Q‚{?¨’WÒû§„éˆv¤^sžJ]˜DM~=~U¶É~”µ\”¤a„¾] Kn‰I‹U¦—mÕ´tå™oœ¤f‡ž^s›bZx8s^3›‰cùx‹Âs’š\š•Y °c”¤l†S|Y>jK:„naâÌŽÿÓŒÿΆÒÂs°˜aæ†s¸­v¢¼|•´h”•S–iEÀi]¼”x»¨›–h¶šÿ÷·»Án{NqLŽ{I‡„KxxO{xN„HzwW‚mº{|¥n‹†dœ£\†zM|…R„ƒP{…S{Vk~EsyI\u=XrBO{8Kr-Zv.VzAk‰Rp—Kd…5Xu0Wg6Ib;DeKQuYX‚V[pJiaVŽtq¥˜|§¯¬Ó“Áá¿Óޤ«t{–L^v:GU)/5/.'QSJq|­d®b¸l·ca“?Wq5d|]`C€kDzqA^w\} j†§fxªdz±‡¨Ôœ·å™ŸÆq›cfƒLd{@Tn7Q_=emLx‘LmŒGd~Xp’f|‘Uq|ImŠ\yŸx»€±jq”^l‡t jz‹KI[:U[SkchŠO]…JWsEbvG\k<@U;AJ!KC(|Q'c¬US€dKX1:i??O9FH'FA*RP2fi/_n=€b6j VolTw…TdtSpxJv†DVmOhG;mzIvSld>WeEWX=Yj;`f5NQ7Rd7Pk8JW2PV3bV3c_8jaAQ.\J'Z€4ErJPp7Wn>ln5m~DG}^\\*FGEnO:]%F="f=¢o+†°ha¯s—Om\p|G—a±pX†Tb_7lƒI‰_H…j‹J3ÐPH‡dVK2q>z=’£f“˜hœœa{–i…xQ‡iAfuD~>š£aÚÇt¾—ez`“ƒS©­uŠ®aqQ•A¡˜LŠŽPzS9•k1l©U}¬N€©_†š^r»uBŒTP<#_f5UoE|€9ŸŽT“’cž h®«eâ¢l‰—j†—hn¦u§‹NÈ¡m‡’m¦°Z¤Âu‹‚^³kI¶g`blmH™xE{ˆJ›sGšŒWœ“as‰T\‚? l7¤ŒmÃ`ÿª€ÅçÐÃ×¶„阀šhgrKqn9~ƒGužci…Mp™R_¹xQ¦lVj/}[-ŽT‹¥U§Và¡lÆÿœ°Õh[‡M[t8yƒ8|¥VTw.lp/‘˜fÏƒŠ©mp‘\muK²™i‹µrye3]1”uU`ŸhMˆMa‹NŠÍw›Ôm¡d_v>k…EwŒQ^yEgc:n}Ent@‡“V~’[ŒU€Ÿa‚{@wY8}F6§Œm”Ï„€©`—›\šŸd›œfŒ—V‹ŽM’^{ŽM€‡F‡ŒPÀÁ†©gbvN_£aXq:eS1Æ¿Š§Äy fi¦Y€£R…•Sr€Q¼œl¬ñr™GŒ˜OgLƒM›ŠY§©r»Ð„‰ªZl‚Dn™b€£_cŠH_z=q|0ˆA¨­d§[vN”²a~«aƒ¡^‡©lt­n¼¹†Ú׉¶X¡“Z–‰SˆmKvnIŽpH¼”b™ša{sGo‚Hi€O„_¯žo±˜f¯ˆhÒŸs¶£k²’j˜`¥£hžÃv™§l‡NzM„š`Šºh›¬s¼•sš“p­©x† ]‘O‹}Q‡‚UqŒQk{Mv~S`ŒOb—[zª`rˆE_v>kˆY”¿ á”~¿iZuCXh>[]=[VGuxft‹hc{YghTx_T€oY‰zq Ÿ–­r®Šn¥sŸxQRP,=A.;A+J@/JI8w{V…‹P‹•^¦º†¨Ó{ªQZ„Gd…J`~FNmAXnBcpBcm:i{Eq–Z€³o™·m›¢\‚…Jko3SM0XG;qsDxŠ_Œ¤w›©h~UtƒOwˆQlKjs;hl9_n>n†W{•]‡’Ww•c¯€™Í•«×“¯Ê{ªVgƒ?Ol:H`88K%9>.\]?^GZƒPi“Rh…ETd7Ub:dnJu|[‹^‚’bh”]j˜mqŒJWp99[NYk]k{O\g:Ti5DW5Fb6Nh4fr5;PA[?@W,Q\.>U28=(=;?I!6\41T*6C*‰9 h*XÞ’j€‡RqJ=TD];;U1Q/WÅ]:g^XK.M`1=Z;OF)WM,`h>Eq?LM:yL-Zv>WYQjV;g’DeŠPc~L;vRU=Aev3P~I]b0qyCWeEZ^?Ef3ObJX2ES+JG1IO0ST;wk=]pJZ†MZwF_s9;hCQS1Hh/Q]3jf*v‰J`“^‚R}Á\N¥x]\LCf/HP.YU-F~Mw{BG£Q]P;IU'HO(dp0J}PKV+=i7@dBX[7Gw4Ef:€e,T¼{L‹iLuG?uEl`;|?œ­hz¹rlŸfr]¤kk–ivbDguDn\Fu‘YM_V’gE«•P¦ dM˜z\k>A—·wšªr~¯]CŒS:c;FK/oW-‚zFºš[Ë¡r©­‘u³ˆ„·iu¨Wa|EO]3Kj/9F,>@":K'aU&€GwÑŠ~yT “^€ªjoo>tj>gKDwFz†L–Áov홪l}¥h”`“·†¦n‰‡P¾‹Vª³ÓÒ—¤è¨•gƒdI„ƒY…yKyxE…‡Y‰ˆQõÜ¡µÿò“ž{znKqu=a„Cn]3Þb@§º‡¹†ZÞ‘pװΊ©õ³¹ƒn _q™PqCiŒ>š£RèÕ‚ÌÿçJìº=lDEQ'YT&fp+Y{7Y+|ˆL`œIvŽ\s“Gˆ«OS|7qj.ã”X¿¾{x•StzGfiCœrHžµxd²y[¤bk›fj[Ž‘\¢Ùб¹ƒ™­jNgCRK!tt4…®yv³t‹|H†‚QŒœ[Ž—Q£†W~‹KˆzRe—Z]S2gG/}L<ŽƒS{¬Yœ¬e}¢a}vMh€GnzCyƒL}{J~~U³x­Ê„»Ðˆ¥¾xàÑ™…ß–f©eÁ´ƒ—ÍrdT1‘sB†•U‰™Ru‹JwP¹¹gˆ°W}”I}†H‚m9ŒzG‘~L¡¨l}œT^}Bs{EsyI_uAnoM^u5a0Š~Ky…Q|wI£žl¶æšœÐ‡›Áu•—g®¯•ZymGqmDzoByOŒ}Y‰LœŒ\Œ„Rw|PpnLkP™“eŸ—j™‘lµ°…µ­o£—^°V™•U —eñ¯x¥ _Žw@|E˜“^˜“e™}]“wb²ƒr¥‰e¨—]‚€P”N€ˆRp‚LŠˆ^•QuNzžZ…•Rkn=\^Fy‘p³ËªÖá²µç”|®T^q;JE,74 B@1ciOeqPbmHm_H}^M‡f\…p\„„_–_¢‹e‰’^etP`lKllPa`KPQ;IY0DJ&D:6{oh¤±s’­Xi‰Ih‹SnŽZqŒQv„Kh~Bjs?c~Bf~L’„\Ÿ–PƒƒKŠOqˆMgs4RP*RW0fgP†„n•kpˆOl}IhwKru@^l8Sc/KU3V_DhuJvwN}‚f†¡{›ÇŠ”°k„ƒOwl5QX)CM3AU48L(:D06K8Hb<^sOoŒL^{5EY&5U*8[8FsIKR^ƒam‘v‡¤wy—WWoLQlW]‹fcKAe=FbD>gI;^HU81V+EL(“B"”{/BئRksnf9]‰H_‡N „KUÀsKf`K^3Zl8h‚F[‘_JgL>L4IJ$Vf*^[7xDz’`c~S]uJRyBBO&9M+EO"IV-O`;]y:xyJE}Oˆ>4ÂBU¡fGo_5I);H);P/KN#€z<<¤W5O5EL K[+dd/5N@V/gb.MtHG]vb?^‰\Gt?Wl4‹nC¬¡i~¬y|˜Tž®[œR¦E²¬a›’T…¬eyˆPwcNzoY“¥pª˜oÎÁ‘„­mf{J`b8erFo‡Lžt„ÂŒ±Ù§¾ñ±Û‘ªŸjÎφÅí î…ÈÄŒ¡üœRj@Y_7t„PsŽTbIZ…G{ŽLpŽArwn‚Dx‡Iuƒ>kr6sm:`s@g…Imv?ci:VZ2TU.[[A{€NxJ`y=^_6]Y?rcVt‚ScnA[S1OQ.]`?[iEZdBM_G[k@Tc8^TR>WfU€†Y^q=ZtA^{=Rj2A\7IxJIWZiz«tu˜km‘cs‰hzƒRdpM[u]s’iobp‰Wo–g{ªijŽLNkDOc8Pa3Ga0<]-8N*1H.;U-DS2PT7[[=RW8?]>Lc6R_7Wb9bn5!-+(&?(!U6$Q=+iF2mp;XƒVBlMa=E|:8ˆJ5NLJ\SHPL]Q8nN5€cBˆNy]kŽiM†q5[QPK;DK/LD0LW4gW5cQ7^eAlgG[eDEeJhC9‹L/Sl?EII&G12$A'Y=!\V*k]1bf4alLj€Kz…B]uOUTEGL?XF1ZP*zg5nh57bQDH?BG%BQ-CV2PO*Ac/BKB>P6FY6DW8E_ž\YP?{l/R‚?F`JTT,9N)MA2†a&;—\BMK`T.Rg=?y[3j?)K;?6+UN(UxAEr70X1@@&•>q‘9\ÀFm\NYByO.žŠ=NÇyQmWAe>DQ;BT1[g/hu;L\:uJ3Va<5MHC=*NR%U= _]8|u2Y SE‘`W[>hw;K…TAZ6dS3U|:]}Lq…Pf‚DVpQG[9L[/ZP'}S(tzVž‘H[‘agRM€PJƒI?q>2Q,I<"Xj1jˆAj•SEkT6J.jR&†±>b³o;ƒ[er:]k:]r/‘?•¡\¬Tˆ¨c–°l¨½u”¿{ƒ©f‡­d’§e€žTLŽSQI*s^;f;iƒHˆ‚RšU‡™X¬£j£Ä€š­b’Y¨¥c¡X‚ŸZ–¯b†Pv{M|wM½~^ÌÓ£wœZgrD\V/xmA_s<Ž|Rðû×üÿáÃí­ˆºuntA‡mBœ¯uÛã ÈäŸÚÿ¸Üh‘UsRy¦UŠ©_‚šRkz@cq/la9˜rO•–U”•MiElv8e~GLt??](Q](Sj'jl7`}Ash:žŒS’„W̧–ÅŽ‚¯u{£l…“l›‹l©”…¸¸ï¯éÝ¡ÍÿŸ¡ºn”˜Y{šI…KxwFq\@lcDyh=‰dJÇfº¤nÑ e„Ilk?y{S“T—ŒT}˜ZsTw€Gcp?Wb?q\F˜gVŒ{bzƒ]rtMne?jc6ztD™Vƒ‚R‡‡Kt‡Ci…Hs}P~zQ£uW¢‡b™¢z‘«~©Ä•¹×¢ªÎƒt–Pei@]X7KQ5BO2?L-@@,GB2hWLŠ|g°‹k¸ƒ`›_‹ZŒf¨¨zÓ¾ƒ·­fšˆh¤g…{Y‰“gŠŸ`u„ZŒ—`pCj‚Gx„Cw{Drq9_n1ZnPyGl‹c’»|‰·ZFn>:D8DP9IN6BL@\kd‘q¢X€p9\X:arCZ…CMvJltW€‡^sb‚†_xƒUi{N]oCSdDQbNYw[Oz`X}V[ƒJeQs}O~~I]mEL[6HS0Dc4Jf>Jf>U_7Sc1CZ4J^8VdCijS‚~T|DYj4PU3NZ2C:$=A3A73L;.MB2`=5UG6iT@VfK2mH?QCJ7;R13?54:941D,>7"V3(<*˜fCX’bFvvMHM?e%UZ,He0@E9=F/fHWU>Uj<:\?NL6oY#Rw9TrNVeGYCt6Dn:5V,`V-¤m2\·^D‡E\C_t?Ÿ™KqÁt^—TORLvLUV=p{9h_Cld=b]ETO64P<<<(?T$6Q)HH(nj*mŽCd{TYUcŠPN…HQc4d{GrŠIb’aUƒZVq>Qw?>ZbV4u]Cow@ˆˆIt“Tz…Ož•c´Èw¨¤až´p¥¯i—eˆ‘]”˜d™Ä{¥®|§›m ‰qœ¯yè礙èŽs­ZRc6\X,CA&P=ÿ×´îÿÎÎüªÃÿ«qÿŠewDÿ¼¡ÿÿÞÆÿ­Ãø”˜¦_µŸj€©jƒž\€‘=}=a]/Vj8OK.m€JkAJb3bH)WZ5j€LSq?=^0De/Cb*Rk5p–U‰¢g”ˆSŠRvvE \?“ƒjg`@•^U¢„k©‡dÒ}eƈpó•ŽÜÇ—¼Çpœ¿_“©YrŽP|rM|jQŠXx†Y“’cŸŒl¼ŒgµŒ[”}K|c:vmH‚|Y‚Y„™a{‚QWb>SI7lUGƒdOŠgUƒ†gk}•eyŒTwuLmpKwƒQ‰{LfDfAg†CjmI‘ŽW~”Y¡`”®t“È…œ¼Œ¼É£ºÝ™œÌtqœYj|LsyI\sE_kMQtEMV<]pPuƒe•b•{KuM„‡P„€Q˜‡g®‹e¡€R |\³‚bš}W}gY—~f|‘[‰†^~Y€–]ˆŠUwGl{FZ|Dg}Vx‰Z…{MqsB[p;V`?ibC1T^Ko”_lžZn˜M[{<^`@^bCSkBXpQ‚Sg…JZn>caG^wMdOc—b„±Œ£ÎФ»pƒˆNotPijPvjg¨‚±¬n‡BQT+7;$DN.Zj8[w?Ql5F\0H[0HY3Mc;Me=OlBNfN]rbjŠrp zq§u‚¢\qŒG_nG^mTdyW_uJOh:MaEUgDUU=NY=R_6Le8GdARhNXuO_cHg[?hU0CT.BZ>HL:T@=iL7dW=MQDA;;g42LA7S=0pP6JoH2gH3>H215>)'9(83">6"M3#ŒC,\|H?}mZW\?j@TYEVV4Um?U`LQYB\\B^=<[@TL*\N'_S6bT4PT8YJ:uQ5b\?I`CFX?eP+eg0ˆi?c}CNe[NK6?d34V1I9,JZ&;@2O8)OE$>T7=I::F/EP.RM-Lj2MXE&T9+4+H4qP"~o/g›VV›kauS}Id–MVvU>Q-X< †J%cƒB@o[>G9F`=ncEAvECNACc1RQji=t™L]–JpˆJo~QxAo²SgšqŠ›_—¾elÝv¥b‡—PT™ccuY?zC=E:W?+Of7XX=<^=BN;PI5KO0OX4fi0^„CTyJzeGj©VX¦or…Id‘Vg€W_YQ|TZx@^€DlS’¡W’¯f–¯k®°cžÅtm‘^j‚Dj‡P€€A™P©¢a™Ý„~ëJ·‹IfRZ`8Š–Ex¤bÈŠPhá™Iƒb3jS:Q17Q4?Q$~V"n˜GF—Z;dMZi6ƒŒJw˜YO“YMrBHT5Q`0Jn:J\2Jm8SZ9}h;Y§mJ:)CH1Gd?S~WWfr›{z±‰’¿‚Çr…¦_zVv…Tk|bxj‘˜m“ŽSh„UnyX{{L{xJ{|FquDXnWny”Ÿk‡›Tdv=Ga2E[:U`MO8;Z4-XB2V?8AC3M72D>'B@2I43U>*lE4Xm=9zM-^O)=J%435))E.H?&_I'jFqxR`jLj\@cKQU3UT*DX>MF9K^4SJ2HQ54T7d=-c])`gB\^9yWB…N17'?:$4R'CB%ZH ZO,\`4_vBS‹EIˆNH^>Tj:B€DE`DZb+Oq5bVD„unz@XdcqPdV¶xÅè¡Í𼡶“} j_„KW…LJc>_b)h|=¨‚O¨ÚŒŒì•Ì…œÌvoØ•f`d‹Hv´^ˆ´d˜»n£Éš×’‡¹pˆZ‚À[uÙw³c¸`”Ås|™oqoEkU=”rRÄvµ¹m¥ËzЧy‹›i™“f™–j›cO‹qbeŒw±{œÑœ‡‹`‚zTØŠAÿ¾krÄ€cl6tW-ò¤d¹ä®náxTÖÑ¢‰ŒRˆ«pŒže}•Pl“O†–U¯±r¡À‰Â¤‰–yy\¬p¬·u§–l–ˆ_¥®f´Ãˆhž^ÿŠFÌ¡z™žwÄ®sÔÓ‡®Éqx~LkS¨‚u¼Â…ÇψšÉy™—_nqNTV+ix;““]w©eˆ‰T„ŠDˆ¬bͶn´ÐàÖ²ˆÑ”r‘Gƒ@—£Q®a®•bš›k{jwŽJ£¡_¨Ë•™Ãˆ½³s›Âx¶¥X¿Ì|ÑÒ{÷óŒ¾ù–°õ’¶é¥Ô¤žl«“s—¯³¬nšb¶¢b¡–[™l±´w§†U„‡Yr›XVr9bx/]j6yV8‹qL¢¥g’¦ks[v~H„™Pi–CVi0™xZ²Ìx°RºQz¡amOˆ™]Èi˜Èq™R{z<{ˆRi|E~]=ƒ}VwtQjX8nsCy|St‹\OŒXP_Cˆi¢–a‹„V”pRˆ{Zä´‹ïïš×¾sÔœdÿ¬x鲚\dV¨›x§Éˆ§Æu•—[»hUž}^rx\wne…vn™€s˜ˆsƒd˜|V”€YzwOy{TŠ|drSZ_?^oFpnJ™€bu `„™g“¡w‹ÃpyšJz…;^{7quEp‰K}’J€Hvw@su;G!?H#>R#@R%Cf+Z`1ho9e„O–©r™®^p‘L„›o®Ü•Ñÿ­Ëÿ®Áõ“¼ãŒ®Ì~¿æ‡¶ì‰¬Ñ—ÀߪËí–™Èqƒ”d¡‹q°˜o”…\œ‚d•“z©º}–±[ky=HK'C?0kkQwŠ^y–h‘­wž·vš¢n¦e¤f•¹q’Æ…±ÐŒ®É}°`e{AelS„¦†ªìŸ¡Ñ}ƒ°ck’Kcg;VV;`[>e`?g`CbiQtpLloCgaNua­q•[zqV‡v[“‚eŸ‹xϳŽÂ¸{™‘^‚|[ˆy`œcŒ´[sŸPW‘CS}AZ†>e•Gd–BCk/6Z8InSxŠs £t™«Œª€™²µŽ–·Ž½›©È˜¬Ç§dt~Poq=Ve;YlLx‚U{ˆLet=LZBOWUst„™kt|QlnM_mFKdG\oN>14\:0[P4UR=[R7RI9R>5JD7N?3H@2^G2\T4nQ6…J>‘nYn•jM¤‹TNu`NcVaTFjM3_n>GlT:UK3F;[C3fa&]‚QKZTLe?\cAPkDm`Kz`6{‘S~ŠjQ…bXV^ƒA:p[;caRc`OacKViKAbBYE-^L%0R@=;4WO,Jw?HiOSj@rVBµkFY uD\sPT8Hp;5T>GJ)JI"1^>0E7=;*2I);=*BFJD&bT*\W.jb1U‚>?‘TR`QXh?G‡S\jLN€Dy`@Ww>POHuS5m…L8{`PG8M^-cl0ZD€†HvœUKœ_Fe@Di;Ea9Ha2wd8¦£GkêDˆ}HM7Xl9oyAt„Lj™Md›YsRV}LfySGqF$CT$?c2XS,G€/QoE_yFoŒR„ªV޼g]¦kJ%lf9U£OFxR>d2CK#K[%>]4=Q+[V%ru.PqN\W1ec7cj=Xh<|Gy½wŒÂƒ´ß¢È䞺—h€d”kGowZgoHce@Gr7V[$\`4ša7²pM£²h~¾…”¬hŠÌyo®p…»l’ÒsƒÇp‹½o˜Ày›Æ}¥Ò‹´Ã|Ú肳⇔¬c¦ª`¡ÿª㧈fKiJ§‚V„¸u °l’¸x’–q–ŒUpšuDM?b7'žY<§—ÂÜšn¾‰yˆ@oigUŸ™Xk´Zf‡?j†@ô‚R®›e§¢o Ò›uƒPqwMònL•ž€€‘dŠŽY™˜dÉÁ†•¤„«„]–¯y¬¯r¬Ó‘¤I©u@™‚N£—n¾”^eƒS|=¢•NŽ¡q —_š°ej†JƒW@¼w^·•r›£s‘¶wyŠVScA3<P_,f‚?h€=m‘My|AexDÉ¢p¯ç¢ÉåÞÞš¤Ð†}£Rl=mŽ<‡JUW4[k9pkFVX5k\2™@‰™Xn–g}—a‹±e¤ÈŒÈØŠìò‘àÿÑê“·ö£¡×‚±¶Ä½Š§Ð‡›µlž˜mŸº€|¢XŸ‡`t›ZuaGšOq‡GUR3mqNUsHWJ29A"ƒhBºdf P]…HNxDOj3_t;¤§v§Üh–Dk€4e‹9b†2i‹/„†<ž²Zo´Yb‘IyŠI~’O†vT‘—feqCjM9}‰bЧly’_•£|œÏœ©¤z†S|yVˆ§k¦Ã’´ÿ¸Çÿ¬µï°Êbª¢_Ö‡Qÿ«€——^­„\±Âx°Çw’Xn]‹‹n²žÒ·‡¨•^¸{Z̓gº‘d{yU˜œ_–]{pUp[†kY‰cIˆzVˆ™\£€SÛ_°¬cÙ§l¯¯t„¤UgvGszG\z8ks>b‚8[t6_i;Vo:il@jjCYh0EN&>W'>a,>\,@]*7d!6ULf*y“Kš¹[­Sp`¥Ä‚¿×”Ååš Ù{—¯h}™[„žo¯¿ˆ«ß¥Âß²Ã墯ӔÀ‚²È•Äɉ®¹c™¢i«Ä€³Û„Œ²Zp–I\‘7;d,>P8bwRoŸo‘±˜ªd{”`r„OepEibH‘’a¤Çx•Äu‘´pl™S\~Iƒ•wºÏ¢Æ}Žªpz•ax€NnsFqrEtoEppLi}Sn‚T{wCipLp†^žªpŽ¥`€†Q{„_‹‰\|Ždˆ¤w‘¬gy›Zr–Uo’Km€L|ƒS˜Wq’Sj‘Qk•QfœSmšIbŒ@Ss>ZlKp~X‚‹eƒ–l{˜s£yЧ~¨x¤›mœn•}_‹yY{xGpsEXk:Pl?]pF`oEdkKcoN`mN…r[¬xVrCeb6Q^:KSGL]SVF7}S5eW;qK>PJ=CG8I81Z@0BD88><*-1V,'OC!V4.ŠB,ºqB•±k}£Žqz~RqZKVIeY@FhHFKH?V41[7aD;Šk6KžQ}^YxCqƒRowSzcK˜_E™’S‡“l}‹n|tjTJ¡Z>…rJyp[[eSJYS9V@HP'U]-Pe>tYh—Gj§p}X¼Œ]ÑŸ\L²SZxhi>EL"VM C]-ETFAc>S.:S*DK(eD&hx4Q\a^\_ƒPesSP‘TNiIAU;E;'„O"d}GRsPDc8F[=nA2P=BL(qa=lŸZI_9X1?K&=[5`F$O‚v•A¶•W¸Ñ§½ÜåŸïè–â¹pÍ ]±¦fºÁu£»iÚž`¾¬m~“VƒV£¬rÏÔ€y®`¯ˆR’™j‘”s—Ÿm¶…_˜b{vDa@OjFC^>:L,€W=ˆ®i¿tw¿…„¹}‰ÌƒÒÿª©ú“a˜P\”BY™:Q{.V…-Z€/›‹V›Îw‡¶iš¥a”§`›²p¿Î~Œ¯msž}y­­–k”µœÚáé­Ä½rsjAmI2•lS¼ÓŸËøÁÄþ²¸ÿ®§í‚ÀÂrŸ˜U¨uOÁŠQ¦»d¤Ö{Ã{£¥s²»…¿¼~°¿|¤f“sI¦sW¤i›ŒeƒŽ\yˆV¸™b¢’^—•i‡§l‰¨cŒ[—”j‰¨W¢yU¥‡\„zP¿ƒhÒ´o‰œNdq3]f5^q<]t;^q6]x4cv6Zi7BO(WL7V`;Ei4Bl/C[,FY+Kj,?n)Cb!Rs't‹7§Bp¢F—\Ÿ®xªÉŸ£Ù…·’Ä’œÛ£¢í¤«é­´ä­²é§±Û¥Ð¤Ï„­¾‚˜¹cz°a–¸¨Ì}œÆl}½_yµWX•BWŠ?W~X¤t’¿z‰±tŠ»|€Åi]–RiƒOp†^©j”¾r Ô‹ŸÎ~µgj©v•‰–Ç‚†»}­i† f—Sq‡Cd€Kf{Ps{\‘Zh~GdxSˆ•q®µv™°awšXo’HqGq‚Wƒ—b®TrœUt†Ljr@]^7XhLpŠ`|¡^o¤ht«fq¦Yg˜N[v6GJ-DD@YmTb}or–‚¦†ˆ·ƒ„©x~^xNxf?q\=UG3FJ3IX8Jb7Nc?PcFZnCSoNXsPRg=XZ;KY?M^;K[6DW>JZOUqgc]:k]BhR?[N;_=3UF5_A6bFzeAxv?€pPtdI”jJvGµhU¿uM›‚WŠ•vq„icXXnL@‚T=…iB`iI[eLBSMGLhS<…]7¡yC ª^å•x|€u]JfhKt„WU“YHeVBP1JQ+]c&dr4g‡LdŒY[‹UP‡SL|ILdHGc@M_4>m>GX=qW4_‚CZŽeWqXkwVYMBƒW:kN\X6p}88ZHF9.BD#CT%dZ(\~5MhIa]e3GP-Rj._x6g‚>J…A_d?x3€}M^ˆYC{KFpGCg;hn7§Jz¸s{“ZTˆG?i6Pl4Z‹GJ†]RgCdc0U{8R–ODƒLCvHS}D]‰Lq~LS‘Re|PH—MLXDVZ1c2p—>_’4_1[†+U~'Q*^r)Rt?IuA:U=QM*w€>y¡W:œb,A.NM%8b=CQ+Sa-&Ôc:rªˆgsMÊ_›Ø¡amXYS0zL5¢ kƒÛ–…¢l·¶kвsh”R‚’XŒ¤]i­p‚ƒV¬cI•oPz…[¦ƒUÿ¥yÝÅ” ’c‚„X¬†e¯¥y»˜w†~]ª{A„‚N…¼s…Æ…pŸZnyW`ŒX–“V§§k’“b}†N†ƒZã£çÿô±Ó¼w]TO4DD*YH-Oe9\T6g˜g|§WãÄo¢é€¯S‰·tT©mTn4X`.i_.\Y1{a9j¸mŠÈyd«Xq³a~«[¥¾d¶ð‰‚ü”sÏ`ˆ­O¬·W¯ªfÖ´„Àz‘œkƒ–[¡‘^£Ï…ˆ¿o‘±Pk¦OX€Fˆ£t¯€©Ä„{¬_—‰U¹ƒÌ䤢ؔÏÓŠÄô¬€µjm”Y_ZBˆaN¬Å’°ÿ­ÎvÞÔÕÿÀ±ï®Òÿ¹ëÿ³¢Ô‹t±l¶d|³eX­Ul‚PržU€¦\´œf±™^~†Fvp9rx>˜w_Ÿ¦l¥¦má¿|Îá”´Ïíͤӹ}lX6DG(Yi2‚©`¸ÙÈÿ¤Ëø«Í㙨½r·•Y­ƒT¦Œ]}pEpY:¡E·®a¶‡Ù¿”»Ò–›×™—Ø”‡Ãx‚šg‚Y¢‚a¢a„ƒ_„”m…±s†¡i–Ÿn¬b›‚^ªu\žšl{RyXÃg‹\’Qz?[k?bsM\3DU3pR=dSUVF]]^fIhoLlsOo…Lužik•Z^”\fj\]—T—YE‹Q1RE>:'@U*A\&YY#F{7EbC=T,^H+ul$j£Uhop€Y|”QÈ›Vrü”E¥³I€R:[?VN/Ur8l’EvCŒ—?TƒZ?VFIZ-cd'wr2r¡Tm™gz€Q{‘amªmf›Pg€JU‡RB]R?M'V].[v4[…*U}+S„,R'Sy*Wx'Sn*ExK=Z9kY4h’HˆˆA3Ÿa>E2Lf'C\%>e,LW:A]0l_2cui«u’Åx’äŸt§~jwYfL4Lq;VeDehBnzD‰}LLZM>Q-hN'€{Dt}WOjDEgJeZ8he>pmK²j@ŠÃv®w¥Ëo¼Ü…šÚ”sÂ[‹WHi@¥g;Ÿ—nŸ…jšoÕá‹påÓpO[qOwdLs€Hh™V¼¿nŸÞ~h¾yGpFU^=UnX^€XœvKÍ¥r…¤¡ºª‘Ä“|€UzŠP²žkÅæšÀɆȊ¨iˆ¶p–§a¯¿qˆÖˆ–¬m‡Ë”zˆ¯{Ÿ°y~¬{«—qŒ›t‰˜e “f²€]î{Q·‰j|Ž\muFµ¯zÄò§£È~c aQ™³u}´|¡®k£×›³æ­ªçŸÿåŠÿÿ·îúÉkº‹K–_JM_u@U\;RG+™ƒS®w¯¥fv€DbM'{L_sLwh0z£Sp~?^y5]C½…FÜí‘t²XUz0od1ÆŸeÈ¨[k„Axw6¿¤Tÿÿ¿ÿÿüÿÿææò¥£[©¢]Æ¿ƒ‹É‰—^™ç¤²ß¦¢½œ¼|z¥cu¯pÀ˜À쪙»€½×žÍÿª­ìŽ®Áqw£h‡¬qïÎÿý©áê…ÈÉ‚èþ½ÐÿÉîÿÑËÿ¸¡à–˜Ó’“Ò•Ò…•Ïr‡´\—‚\¥{Y‡tBo[6bf:`f:qh=wvCdxF_n=iB€Iv~FŒtKˆvFGQ%\n1lŠ;ž†Fœ~H•zOk\5VM.VlAaƒMmŒK’}B‘tN_c>e^7£zK»x²hk‹K Œa­®u¹¯~ÑМ¾ÊŠ©¬vŽb’—o‡¨|£À˜ŸÌ•¦©z…^‰jU€pM†iMŒQyyCoIš}Ku‰MvwJw|MxxFƒyHwx?mj8lsJx’NVŠAWl3Om3JO,47#54'HH2HS/NS0Vi?]CI‰5Uƒ6c€1fˆ0L|0D[KŠž€³yŠ«…ŸÓ®ºä¥µÒŠª»uª­v¬ºt§²l¬b{ªc„­cs›PnHvžVgŽB^~T‰žd®Ãr°È¦ÀfzžQoRj€=BH4Xe^ƒ™}ˆ´f}¯pºȉ˜Äz¯a}œX «r±Ø£ÛˆœÄmzžWq„Tl~RrŽKq‘OwŸ_~[~ˆU}‹[nŽZiŠ`¤€™´s…Ÿc|ž\rŒG\t4Lg/Ue;hxKvƒFl–E_ƒ7LuIg{ÏŒ­ß¨é™ÉÿÊÿ²³ù¢Ö‘q´†”¼su¡@7E/MGJvxsŸš}«šs™Z~W=fS8JL:DO7TM8k\8Yh7Td:[a?V\8K`DUgU^ybdvZguRZb?@O-8O8?VDKm`h|CapY>RN_53hd1h{Lc‡\^yWkYKX„IH\JUI4€N1i_2,ED/$0* O$Œ2!e€>8“dG`ghSHa]=u\H~qCWrOBb[VRBa_8duEnrQkŽlo…i“ g–“er–nprd…UO¢]HšnP€{a‚c\{ZI„lKJmGOYN\W*CI5P77ƒ>*¡a7Še¥~u`ÇjFš|dSNk>TF]}=bƒGK‡\Oe=eP+c[6Ub>DpTRW<G+ŽX/_¥RFtLdYKtGPUF\c@r_=vV}–]]•gtri—ŽMv¨iAyW=J.LN(?l-GY)^i(?rALK48]/=A"pW"~†?r¥oc–h}‹I;^ ö”Œº©g›eK‰d[j8dw55|U2=3b@"W6[m;NwJOpQb`6Vt?P\?W[6\s7e}/\y?Md9HM&K\/Ug6moC–tLy‡e€UnŠYwˆRu–Q\zM_eCzs4V§K]…K?{@LV&I_)rN,`4gsQpuKe€KjLYŽKUoC;[8BU(MZ)Um/X€*\+QŒ1U+Yƒ(Z…)X|/Ml@[o<[{BFg;td/H \?bB8]&@T(KT+Sn>IbF±sCÀã˜Åコñ·z½œjœl8jJMW+`l/yk:y{E{–UtzI`cHFg;QW6jZ5e…TowERuPWc7ZR?bZ7•†?ž™\q°aˆ‚O˜°fŠÊˆËv‚³nY£_s^Bc^=„{MzŠbÿvI‚ÿÖy„]@–yOh|XžšNœËf©b“®\I³bL3hA+{F8‹]EÅvRš™dØ¿{™°‘¡g¿¸}±ÖžÄ»€Ø¯‰¥—eœ‹]{}S³Q–¤z¦iPp»•bŸí¸‘³„‘¾u¤p|€Vudq¢mhˆ`\pLWsAswCo€@o5â²q½ÿ¯”å£`¯tfu0uo0ƒ|Cµ´xŸ­w±qX”wP¶uR㑇Ö꥚ÿ½—µ‚ˆœvr—bPaJ@H(‡V1—«p]r?1D7H%Q^32H'I:zc.s]@]a:k^)u~=²‰R¾˜eŠØ~Y«Jh“J«ºwÍàœp´q_–`t¥`uºeÛ°[ÿø§òÿº¨éŒƒ¹gªÎ‹¨Í‰¡›`y‹TÕÆ‹ÆÿÖ¦³‚”_ˆ ]Š©jµ¶t¾Ø˜¢×™Ìî´âü·Îÿ°Çÿ¯Êÿ²Ñÿ±Øÿ¹Ðÿ¥à߉«¾}ÞáªíÿÊ÷þ·»Ì†°½ƒ¨â‘ŸÑ|¾Ý~¬Ûr·¿q¿m¼˜m˜Ò~´c†¬c_˜O\wIfsQ…Y†]muAwQ4cVj‡=x N{ WhoFgUBRN.yt?ŸjF•{\t¢bn§[q™OtŽIªŽS^~[ƒŠTƒ_‘œzœ­ȶ³ªv„^’oWŠrUŽqR‚xIk‡Daa7tpA‡uEw€R„…`š…VƒuMƒm?ol>u€R’Z‰Pl„Ig|@R:Bl/2W+.L'.J%.A-NVH~§`l CX|4^3Mn0^{EZ‰[…§w€¡hy¦sÑܕŨu›¿Sx©Ccr7ec7nlseTŠl`‘{[epLOTI{aRjvOSqGQi:cd6S_8]a:[m7I^@P^LcgVXbFJEAQE>SWFQvTK\T‚cJjH=]B;I5g@'nf3ŠuKL]LgVmhG=ŒQD]VdD3=;3?11H+ #'/0,K3'v?'q[9]VHxeJUTVR*¥H1•OwªŒ›xeZÐna˜yKvIZpIŒsF‡—JUaXpA^p@\mA‹XBavBP„aSQBrH2–_9|¼dgÚ­m˜”pŽbo‰dlzXqsT…ŒYi›cm›n|“lM~O4bF;T4KX$=l,Y])Jz3DbDBL%6[+GX)]i4zxDh¦Xr—g³ŽPÅÖdwî°N”Kh5S(AW+tZ*TŒBKcPR^-Xo/Wg5Px@TxHCj?KT:Rg5^~=_‰/Z0W„6X†.Zˆ/S.Tv9Mn5B\0AA#n^4c¦UJ‚PFa(>q{qO¯¿xíõ­šý´_€IxŠF{¦^ƒ”_§Åƒ²ÛšØù²ÍþºµÓ„ôç¯âÿÎÌÿ°âÿÉÅÿ´áê¦úÕ¢Îå®ðò´¿óšs Z‘¶i¡Ði¼X–²U¨°i¿Á|ÁËu¿Ý†ÐÿÀ¢ø­—ìšâ–~‚¥ÁûØШi¡…NŽ…L§`”¦`y‡S‹…?œ…G°“T…qAakMY~W[™_Zš`e†ex n‰¯`Ÿ\k{EaR5ZQ3ZR4jlDŒ~SuHRu‡JYs=qFœ‹f•`t„R_wKj†Wvš^Ÿ\Ÿžt Ë’ƃ•¡w“h}vXxvUasIosCxyDŒnI²qV’`E‰gH‡|Hw€EŽYR{wLywNntO]uI\Il“Ud«bY¥pX¤qd¯u”È€ˆÔ{hÏm^¿oW“OZs@e}Miƒ£u·ºäšºïw™Þl{¼NI‚30Q$]jITwLlw\Š¡^r›Lh†BcuAc}Tg…Xo‚\ƒ–^ŽŽMaZ1RL/TX.NT.?U:RhCSkNX7ITBJ^TfxOVpFHk:HhK[^{žf¡eKgF<[GJM9TX3XgE`bEsa=tu;Š~JQ{Xa]P=Z:7?7I7,$R- :7X#$;?.K989.e1!tW2DŠP?n`JFQiK;nf7apSU_WbP›—MŽ­~„¥†Š’{›bv p^ƒw\_S_YGeLNQG`lJUHRxNAO[6† QZ6ek8Vz;Dt?J\1X]5dc¨mE¦zQwm]ŒwW” f­m[™kqvP:j>?JCkM"g˜DwŒB}žE^ÆhE¢hEU9AY.`G&J‰=HlC[{:Z‹GTqGeU;F†QOYHTu8YƒCg‡6bŒ3U†4X„,Q…,Ux1T€8@z=0h?4:+k6lœE_Zdr@t¢GxÁ}“²l³Æ³îŸ¾’PtVPf4q‚HLš]avCh’Ta~HSz:hs7‹f6op;KW;Q_;bpDVh;muHcƒOFsG>b>8[1J_.e[3>V6SM$Zu0{{Dr–WgzP…ƒLO}R_k;`i;td1fb=~ŒN·»cˆæ¥j¨eˆyAzs6|ŒR”µl‰œg†¯|~šd…’Qx½t‡£eˆFpnJ¯…\£ì­‘“mƉK¹‘[„|UirEXL.reCZŠXq_>o_CthG¦ƒ^†™c|Ÿm²ŒcѧvÞžyŸ¢jjo?ae7€c9qqtyW~€Zm„jg}QMuEsU-»‚S¶»†™´nc˜ZSBe~8Ž{Kt€\rMks_‹rP²…j´gŒ‰_ÂuT~Õƒ›œo‘§‰—tnšf‚~D_W-j}CŽ·e[ŸMIM3FI;GL5`w:Z€C]~FkWÄŠk€’q}‹i„rV{zMŽtB’B¶©hˆ±f¬ˆPª¨d•ž]a‘MŒM·Êqe®f[gCTiNX˜g‹\›¬}ºªfƲ„ŠÏ…q“Iq—U~¥m¬Ï—ºá§Óùº¾ç¬‡À„ª¨fðé«Éÿ·Üó”Ð÷˜Øÿ­ÿüªÿÿÃâû²·Èw¤PŒ£LzŽG_m/ig;–žc´Õ‡Àõ–Æÿ­Êã›ÆÄ…ÇÊ‹ÃÓ‘°Ò‘¶ß›ÄÖ‡ŒPnvHw|P«Žk¼Ó‚¤Ú†“¼_‡‹NމTvˆI–~RެlЬo”«q„¤m›§fŠ©h¿~˜æ¤wÝ‹Yž^cbGXjA^g>drBfh:s]6fU9`f8Ž|<šŒO|Ol|@nŽFw¨Sp¤]°µæ°¨òš‹¹qm“™m|žj‡›dz–]lŽ[me…œu‡˜sz”k•¥l†šfy§hw[fŽas‹agYc‚W[zIl†P| d‰®s‘°z›¯}³Ø”µÖƒÆÝ“Øõˆ¨EKD$OM7k|gŽª£Í›Äå¿án§Õh’Ã^nœDQ‡=Dn8WzVªw ÂÇrd™U¡£w¶ÍližGXq6hv?uŒT‹’_™Y~ŠHm‹:]y?liOltFWW1F="AN#Rh/fxF”^Ÿdªck•Xb”dk†OOX4UK=lqLz‚S¤„O‰CdˆE\|<\sDdƒQd{Su…SlvAmO4»^E~’X}…€Uˆ^›Š_sŒ`2xX.56?:GKY_CaW*`b;‚^C‰g:Š…T…UixdpW»gNlÊsL™£2]WPA5vW,~xG‡†X—˜aO–jHa]Ih7O\7NdTo3HzEjY5[w+`Aˆ:‹ÀTg¿t@ºz<[ADZ2i[&cˆ?nwAs”AXµ`r”Sxª`\ iQQ`t8f…:f‘8Y=]€,S‚,Ux.Pr2gb,Z‚C:‰X_TFp‘?I™U]S9އIŠÄo˜¤rœ·i“«hwÔ{l©|h©mo¦dS†`ZyN^|IZ}D]rCP‚D?^CAK1u]*†Kc]‚ŒYch`‹cfœdv•lZTPd?7W9=D!H7 X_&ŒFv®]v«hdpObeAƒƒ[MsWRd8cb,€u8¯ŠSŒÛˆh®vRtBdh1l8r­]†l?ˆQ`½‡€bI¹¦m‹Ð‡†kœ’eÏœoÕÙŸ‚a…k4azJqpI`dD_\:Öe:§Ä›ž†|…KsF~V6¬U?¥lÉ©kƒbbiGYh@Tp@P^:yW3th7xk8‡fAƒ~Lrw@Vk9yjC«onÁ}nÂ^²jL~4rn(jy2uA}?™‡Q©€V|mJ|a8ƒa9¢O«¾r¹R‡‚Z…WlB>Q'aX)~{9ržNXsBioFjNs›R{ MŒ½j™XŠˆas‹RX]:dF3g\7o^5oH. T>|SizHv^:kƒB~‘Nv¢YŽŽK¬d„¬n|§l›¤m™Ât™ê”s¯[‡~<œ¯yy©S|§T Ë‡Ä뽿ÿ»Öþüô«šÌ‹‚¾v±¹téÿ®Ìÿ¯Äÿœ×ò‡ØÛ•ÿô­Ìÿ«ˆFiv0sˆGt«YPšOhF…žX²ÑÛÿ´ÁðŒ˜˜`uŠU‰›k±n˜³f·ÍŽÀí¡’ó˜q‡PelM‡‚n Â•¢Í‘ È{žžYŒ‰N—o@lh:ˆfA‘P}yHsdIqpHŒ]ŸÎœ½ÿÅÐÿá¼ÿÃo§fY_;@X/?H(f\=Œt@£ŒUr‹RwtBƒIs|@df6h\4riG_5In:HyhDh~HoŠUd…Rk{M^zAKc3@](4S ?] Gm2Zx>Y};[wJaŠ[a“\g–PaY˜³{Éá–Ãñ›±ßŠ©ÕƒŒ®n…–xŽž}œ¯†žÁŒžá¦«í›¦Ñ~}®ez–h“£}™®z¡k“j|z¬”mzˆPks@`c;aoC}L‹yDnjAau6Qk.GY/FS3GU1@E1AWEHfR>B'FJ,ZK-k]?W_5ShMPA-jJ3d`E‡\B„~P„ych‡bSŽqljabwHqp>BƒH*>B"/%C$BINT5gY3_R.PeEmYH‰X6ÆuJ—Zœ’s…¦~˜˜rLÇŠ?ˆ[IAyY2pg@‚kI„—QVŒ]GtS9U;;C)?P'9j9b],z6xzZacP\i>Z{Gpm9r~FdŠJ_dJ~l4²“K~â|l¸®j–X;„yAK9C^0X`-ql0qŠJEœYIoNGlB>X2KE&FW,SwEHrCEa;_N%My2jl=d;OPGYD^e3~xcGU…Eat>‚‚Dª­dkËŽLŒJFt;p^*­ZeuI–‰Q­v“ªtÇ „®’r™®}š¨~·Áv²ºzfYWqFlqNŽdGyQ7hfA—ƒW¸¬uº×±Ÿ§‚“ß™R {X`A€mN™‡c—‰\ªbƒbciI]d@Tc9ag5Z„[XiC[n8Z{;N[.DG1ƒ^B¾°mºçª°÷¬‚Æ€R‘G?s1Hi+He'gv?y•[j~EdxBmvPboH‚zG¡]˜ŸY}Eh{GRŠLWƒEeW_|KZ]8ln=…’Z˜Àr‰Ôi~¡Xй`€’G–‰K€›OƒˆOeˆIlnIsM[^F†gGŒŽ_”‰Zb„Rc‹Ls ^s›WiƒTuQp@+9=&;E%TI0jT3æhK…™TmyJhh7XT-QN,WT,]W7cbDˆwEtMiuHY`@_hDXcGiQ5)=-#>-#E8$1< #$M/0~oOcFJs;fj@H[/@B*3:#%3168u{wδ€¾šWƒU{’EfzB|’Q„°f{¤l„¡`‚”W ³j ¹`аZt¢dn¤lb°gl£Xw±[w—Tv…JizIj~Jr}G_{?Ltb‚>i…Nl‘bnŽ[n…SdˆNS†BHq3?_ =X!?k&Gq6Nc3Ob?h‡\x£p~¸r_OWrJ“›e›Õ‚¯Òy”µm‚œ^xŠf‘‡¢Ç—©Û´½ñ¶Åñž³Øv‘©`}“Z|e‡¨zгs…¯k‡˜k‘~e°zT}n:^V1PS5Q^AetEooB€e7^`.CO):C%7@%5:4>SO\yQ4@/FB-HG%TQ6g]IulPblS]SKFREGJHSF@UD@`NEWLBZSLSiE8^R5`QMbQEo[CEgEZEDNe;NaHoJ+]C‰oO”]UsQMx\IuJoÂlOªƒPjXPZ?Be2>b@G3/+#DG!Cd;_^:td9o^@XrQyTJ|`8lC¸`JÍuK•¥u‡œO¨};R_VP8df@sm?f†HJ‘Y4bH%K5=>'KY*IqFYc3@d@4C5I=Vg,OcBgY6yq-ŒKIKcf:±{6Øvuؤ€u@žF[@Oe2[h6f_4sr8€uJjŸVA¡j9dF9E"JZ,P_(Fb3;r>TP+Ux'fyA_€?KpKVj7Lb?~b6aO:U?VM+oR)NmDSxJ^\0Hn5PW2qk5Y9~€9©©HªÃr°Ñ}cçžL‚gSy:Gm(fi8l7t\‹VŒWc°ZW¤hc~Br‡<\“CV|5O~2Us2Q3CˆF[u@t€BšWv®kjbiŒWX†M\‰ESo4ge.‹Ka—x]jBdyHW‡[d„VpAf˜Yq‹Vb«jWpg€Ym¦lb‰ZXaCWfDwˆTsƒk„StqS\cH\kAh’QBˆV5=1E:%J\AOj,|™Lr¯ggžc\|RUwBeŠLO{A@Y)^f.jŠG²¤dtÓŽcžaKˆYq†J^¬^mZ:z])}r7©•R¡–sƒnR¡b¥k®px¦mƒ‰Uzy\€Y^hM_G1´ƒN ®ˆÄ¬ˆÿÍÕ˰ÿ®‘ïЬ­ç³¼Å‡ž–qš‰_žŒi{c’kNPkQNV1poA‡Rx‡eq†UP~V:Q3gM7fqauL4«J¥®vo•Z`|>Lƒ>Ar0Uu9w–R˜b[…Ur€I„…Jy~UŸkª²w—¤e‡¤X‡Àtu¯nq|AuE…’[l¬vq²s€¨jžŠT¤¦l„”R•Y^¯_~5‰Š<ˆ¹[ŠŸ]‚yJ«wRе|q‡T¨•^˜¶|t˜_u”P‚œd¢i€¤j_žc[yHKˆ?LK3–\?¼°nÊø¯„ØŽu¶u‡£[¥J´ªhõóºöÿÊêÿÉÔÿªÐÿ¶å‚¬Ïp¼ÉqÀÖy¥¾h…«_ªÆ}¥ãŠq¨b\ƒQZˆOuˆGlƒ@dA}ˆGªv–Å…±TKZe?‹¨n—¿x…¹dyªf‡Åz¦À€±Ä€Ž®|z«yˆ§}«Ê“yÀrf‹Jiz=}>™}BŽW§·•£Þ§¥¼‰š«lwvM†‰fÛ“¤¿ˆ¼Ùš°ÝŽw”^qc?YO7CD(JI.KJ/]Z8fb8¦iXyš[Ne7PF,X[BXcAX_>bmEjuK{xH‡Oˆ•Wf„PepB[Q:XX4Tn8d}JyqI|aB€Z?z[Ew^;zbDrxUgQ^oFF[;;;'71#13…vVbEkoCdzJL„PL{E:b6DI>{rg£¥es‚Gl\p—W\’Je‹Lˆ­aˆÃh„¡SgxAis;uŽI¤wÏ–Ì„”Áj‚šLu‹Qw“U`ŒNT€Bj‡V{Ki>_v>b{C]ƒBc†Gi“NwŽV€”Xq¡mª|•¹q¥h®†ŸÌ“»f[xBL]5CK;RQ>ea8]T9bb;Tw@^†SdŠ^zŸ]uŒRtzO„‰Rg59Z!=V(Jq7a~M`x>KwCX~]€…ž»‹”Ât^–Tk‚X«ZŒºXЬOrEjoPu{œ»¨Èô¿Êö­¾Ùƒ«ºa{KfoPwsl…©‹¾|‹±r”Ÿ\„sEcS8Xa;R]5VZ3MPZbEYdK`RJaWEpfI]pHa_IciLgfQ^_MP_EgWHUpD:pT'8R6'&U<Sa1tR4pf:dlR^nL`LGaTCa\GgWH_fHU]JFuKR`CjjCb…TcŠ`]cjKMbJ9^aHYSFTH=VS;qU;PˆHhfW‰]3wo@`kRfUEdXAi]H®_Eƒ^mš~VxXL`>lc9M‹FG‡MUƒLcšQ_ŸjXˆ[[e@T;rY9foSu^I]^AnT”£O¸Äg{Ë}b¸sIˆUCe)Nc)jT&bwK_ŠLWvR|‚Ew¥TXÁlk„\[‚9l€7W SL{Her2qw2dŽ;e}Gk‰D\uIhz=Y~F{ONœS6]6TM|W FpCPh>]…JW_COg5XpCks9tƒJv•T~•e~WˆRr“Tr§a‚¯xsn]ŒePXR]J`e5z¸]i©mHz^HN-_q?XV†ŒJ•»`ƒ²sŒ¬jl®qiŽUKs@ES*Om-VˆAy|@²›Yt¾tyŠNgd<}xE\­X8J^45P0WYPg{RRa>pfEs}G^j5TK;\fd€”oˆ•`x”dhšjy£a|¥[ªn‚½{“³h„™S`v;Pd?_‹V€£b–¥fŠ—Pm€@fzAgTs—ez¨huªdo©j‡¯]g¡C@k.J\)Wk/[zb)Be-Mv@Z€Ph‡Tt‡Yz›o®u¤½~¢¬œ¢ejCWwUrDgr@UV5JSJu{Sw‹GWj_E9u]hRC^a5soBuZ1†G6zY8‘QBlIŠS~[vx[oqUa~IikCb{B•~OÃ\žÉu”Ó‚wÚ’U¥v[}I\p0}S,«f3}†XbdbUTLOe>GS:MO8ibCa‚EK{[e]Lhi9Sh9StETƒGH•ÅZn ‡?yZ[b36q>8I>JP%9[1?`/L\)nn2_Ž@C{UdXC•o8‘»^³xõ˜cº¶Hr\X^3Op2:l?5S*@K&tQ(p7c²jcŽYvf5^e8ea6_l1UrEsk4n©J€¥b–Çm‘ㅇ݇]ÀImFiBHV2AN)IL)LS,Bj/Gf'Zf;U[2^|0NlgyH‡~BQ™§crÇ=‡dMx8W”EnœN‚¥Vz£YwSt‚I€…Ek|BOw;Qz5~s-b¤ZI†ULm0Gn2Jd/Sp1Pn2Q‡FHsDYR)n„CC†G*P,1F5Q#DH\k8T˜T‰M_¬`AN>>J,L_.oX.¸g:¡™dš¸~‡“q}©mwªoy¨v²¬m°eƒzT“†a‘t¨«˜¼¡€ÌÙ‘•t^ÖqWë˜rÒ“|ž˜|”’i›iмu•Ây’°yœswS}‹i˜§xޏŒ}„t``BkvK‹“gm«|LdMgAYg9Wa;UR4TzCe{9t…Do…U]~KdwO^zK†lAœzP…pElzLl~7o•Gc>?V.SP+nuŽŽQv‡Lb}FhT­§|Ⱦz¥®qˆ—^t€Qa`<}U>eP¦œk•·kŠœjƒ‚Vu}Sl‰\b]`ŒYUwH\^G|seuclPh}FQh;>KO¡–Àº€™a­›z¨»{ˆªZ}—fƒª§¼yŒ¤Xˆ|FˆvJz‹`y¢]u¡^r”XaLUzEXxBa„Nt˜j‚¥j‹¢i‘¯cªQ}–BNy4Be3>j8V…DV‡?g„Al†Ng…N…•X‡¢^{VrŸn²~­d}]q—\]†HjxBeIGH^&IZ4Ea/CQ.dA%x|5nŒ^bhŒ—]®k·q¡Ú~SØ»Ck_Ma5L`/DT7OZ,\R&T\1~_;hq:S”^BpBG[-F`)bO*@o1pS5˜:ŽÎƒ¦½z§Ñs—Õ~ƒ¸om»gS¥m@{Y=h:Df2G\4Yh4]l1U~:XqAŠ9Y¾€X|fb{L†›QžÂl€Áqx¹j†ºjy£aeŽSMuIL\:FY6QZ;@^7:N.[b(U8z„=_œ[KsLQp1Iy8Jn;KvEih=r„L7‚eKH4Rg1>o54S#;K$,Z BO't~7r‘mg}N^„ID};Xee4Xi>I]9SU5\^@\bIRe>{bFy‚_s„[qF[y8[†7Z;`9n: X„¡YhvEQX,VC"N=95/*†G3e…NWE"mT5t„Iu“]…“\•²V»ÉtŸÛ…ªÐ{«ó£—ævËn¿Ä€¿ÿ¡¼ï¢Äê®Ýš’³nˆ dk„ImyAƒAšQˆ“Y³£Ó•r«f^€M…£n¥¾Œ«ÂŒ¼ªr’­nƒ_”ªx–¾vr¢Z™¯s£ÐŒ°\—¥Y–Mfk2deK o»µu¥±fž¬b’¤agwHWl4Kl.Yw2•ŒH¤•cv•]t‰X‚yº‰t¥ht’Y‹¢`w‘Xe|JuzJŒ‡[Œ‘k—¹–—Ѭˆ½„™š\ÐÌzü铵¯derGidTmo|™q~•iu‹ZsxJm{Jt†_f‡VZŠK‚”^‚š[j‘Y~…TµŠaȉY¬†P¥~R~sLtd@ldDob?¢sZÀ®}ÚΕ²Òu–œU¸ p̼‡±¿ys›QUl@ndKˆ‰c†”Un€Hg{Up‰Å·¢ÔЋ~¡c€gœ£q} x~š€¦±‚ §a’Mg‹Pp[}™X|–^nŽ_xg~¢go™Z^ŽLp‘`†¯j†§e€„Wy†Rr{>_r:Mk7Cw>UF\†@d€8RzCpHsŽBk„CkƒFcƒGnˆQ‡¡cr’K[fRŒ‡mŠ­\Y};Wk;Yo9Ukx:ke>_cAZx;U9LA5lI4_w8I„R?WTOH@RKthCqaEyiH_b=hsGYq@;`FQF-Ef2LsDitN_–UVdVoRFbE;\BB?.RR'Mh/La(`f%vo!Xj#\Y-qu8]œNSƒ]Le7iY*…s)v‚CetX^yFn‡O¢ˆTv¶^H’IjQ[l+M„;JxHLk64U9/J-+E1`D4zu6vzQv’U‡—Ry¨]›T­Âp\LJ@szFS3@W(7I&OC!J^%PE'JU(eM&T„6FaId64d4=H$GV+jc6Š@ÑwŒÁ‹†¾ti«`f}Jwi3~€6a¬SU¡XV{JL€CGzG[c2Nw7[|?ž•>eÑrh¢v©U’®a€¬`s‡Kt€9\MOgBVv4MrCKcA@Z0EZ*0Q&BT(Zn6b<…8Z¤YHyIMk2ds1_ŒESjA_eFX*Mf*5`+¡„UˆœqwlO~a9xzQt]C~iB‡nEÑ\¸¥y‡™c}Ym†Fl„J„ƒAŒwN`vMPi6`n3`z8ox8aŒ;`„8h‘K§i¿Ý¤•¹_l7UU-gs2m};NzRd]paSfrWHa:i_bNPnD5hhDV[OAVNJFFPD/V=4~J2ˆgCtœd_WbVD\YPqbCXuDhlS{WG”|Mƒ§iLŸyVXgˆJDeU?SDy|H`Ÿ]VŠSNqI[oIVf;\h>S^?KX>JU9U^8TmCHrOF`D\i6“`=Ÿ†Eœ±i‰Ö˜pËFª€GYREX5GF-WY5Rb;Fa5Ic2Pr)Sq'Xr"…d&m’6C…S`p:|†;YœQFtCHt5Zs=Nd.;\)UN'5V2?I#J\,Cd/9Z)ZZ.k‹BD¡cgm8g•SU^Dlw=QtD:D/96|aHap^xlJ~iO†S;gT?‚jE•uYxsa‡ˆ[wª\d¢Yc…Gea8Xm?RwR‹AV~;[|@‚‰Jƒž_EuB4N9*<-)-#&%egMUl?05=R,^ŠO`²\Fi2SQ*ke9{s;º…W¶âÀñŽÕÿžÃ㊣µi…KOS0Kd6Uh:?_3Jf3Jg6Fh8PpG~•fš\g€Gdvc™šm˜i±{Ri?rwH~ƒW™¿„j¼p„¥n¡Ò„Œºjo€D¹’R± d†‰SdqFhH…ŸC‡£J{«T}·Q‡˜M–™dŒ¿xc‹KT`1kz6[7Wn7J\3cx@r’Jj“Ml‘R¿žæ›¯ú ”鑎ÜËŠ©À’ÃÈ¥Ÿo‘_š‚pŸƒi¢~i~…cdmLxhF–jK‰|VuzOw…V|cˆ˜o ¬x®©{°ªv¯–q¦–t‰•b{…Kx‡L„~?|yLœ‚\ª—n—›c’]‰„R–|W—^”“^²t®®k¦š`‹ZX}ŽeŸu§ w­ŸjŒ¤c³¯t䱃À s ™`€Rxšj‘¨z™´{Ž›bq‰Hf‚LxZÀ”tÀ¯€°hm‹f‰£u™¾…’†’·oƒªs™Úªð“«ß‚£Ë€ƒ¬kl[jŒUnˆOv[‡˜_yŒSp€PnŠJXr5Qd&LY#HT'IU9czZqVf‡?N^)Q[.P^:Vc=Zg?XjAWs=]p9Sm6Ic4_nQy’KZ}1E]*AY3Nl;\m=XuDhtEmf:Ye7_v?b„Lu–^†¬eˆ§Zp‡Jnt@`u9Nb;L\3JZ7VnKw’]‡£fƒ™Vp„HUqCEpSQ{[_zTXmRoo‘«• Ï›™½yi‹Q]b@^c9cg=ji9b`?hrU‡auŒUr‚]ƒ}T‚SflJ]fRYlU60$>8#@=!0=/1?E[F7mV=kWL>^MQHNlBJv5^J6|u3[”RV€]i{JVŒBEv@H`4MX1}m6›Sn†ad~I8ˆ\QO6ko/\ŽYŽ‚S‚¹^°‹>¦g/`U3@$5>FBYDEa,0b-;H WG%]a)DzU8U4FX*Je/_Y2m5«S±¹‡·ä•“ôªˆÙŒU¼g;•[OyCw„Gq›Ty¡T}¢X…œ_…¡[t©c^}RXxKEfDK^4Dd5Od;Ht3Rn5FrEBh=KV+Tb<=rA:Y+:Q KQ*Zh6Qx>Tn3x„8OœZUnBSy5Gk@9c.7W.3G)5H*;M)BZ$Ae-?S$IP)}b.S¡O|ŠRF‹NWb=Fc08H,.D(5C*DO0K\,G\:Um7wv1’ORS{]8^J>nHAL!_H&hh5_J\sBN_6_i/•ˆBÆÂf›èuÓ„„¢ašÈ~ŠÑ„_›^i‹FYŒe—xAm]j‘RZyF^g7s—Ku­WqªfpžR³^n·^k”WQkQŠo?À¯}ÃÂm†Uns:x|S…™h£r§„_âŽd¼Ã¨³€Ôć͹ȣ~x®‡sxZIxD]O)zd8atPn4Ym@pˆQ‚¥]fŸYcŠYˆ_˜‰]‡e>fO0RP/pc3a[C™žp§f“™Z•¥hk•X^œh›o «cŠ‘e‘šau‹C_|6TX&eY/ce9TH1liO”¢{€¤`ZucrAgŸ\f£VWŠEiwEš´u¶ë›«àµç–¸ï¥£ì~’U˜eTŸvbŸ€kº‚|¦¢~š´ˆ›¶‡|•t|nVƒcI„sKwsMmlFgfDmlFxxKo€Ks†Sy›V•ŽZ€‡[xyUu„UZ|DMm6Uj9ls=vyH{}LЉV†‚T’TŸžd”¡f‘Wš€[ˆŒf„Šdˆše…£o‰žZ‘}Hš…Pšª`³¢l§]„†Rˆšc™³v¨©p–¤jvžcs›`sŸ^‚“X“ŠY–Šf¥¤t‚³o_£n…™€ ÀŽŽ·x‰»…¼çŸÆÿ‚¢Äd§µp¬·t’ªažNt}?guE|vMzsBwuC}…HMx9?\+9M1B8D,TbLu˜Sm‚@LW*>I+KM3C\:B^=XU>_m?Ru7^g0Kd/PhN,Db>`xVraq¡ki¬r\¯{a²—u¾—ŒÄЉ¥ZeyLs~o“²’¢Æ•“¹kr…Idd>eh<`l@_zJxŽV•T…yDogCeW;_Q7`\FjqOcnL66&97&35$G-$P;%=B/WC65Q0LD4QH,NN-ZY6VlCQsIXyKqmSDŒ_^o]GvI_lTÎQGcƒTf`nuTJiXKGRNP<>??0TD3eP8QB=aX;Z_@i_L[nJje=šb4½ŠPvsj\uxk]a]bQbNG_W3u^DgAN‹OHYAjD.p`3XpGgWHˆm<£jf’ˆXWKCS.FW0P^1Ai>F?4GQ&>U2?M86M/F6)NTDa7zZ4ir=U‡YY}QE‡QYoJjzAh–Ve‰OTuFE\.LZ'j`#Sh4<`<[i7c{9Y~DZyN_„BQŽI?pLFb:Ud:oaa-Kj7Yu8N|7Te5t3NTThCHu-Ef/Ao.:X/CC&@J(;U4JW'7j-1H&?HQ`*jl6`š`RyEIb/=?">G+Ta/\_AWc;YdC]j8Ws7cq6Zt>W{EbIa„F?{HCV'>K'NR,`vAZr?Qn1Ps,„f/Âc­Äm¡Âm™ï ß…„œcfŠH‚>c‹M{‚Xk–QQ{RCY-[T-zŽC€ÅsxÉtp¦i‹ž>p¶V’™R„‚SÃX¿¤k‚˜go¢^©|DÓ—aŸŠj°´v¾Ü“Чm³d×­lÛµ‹š”u©Ÿa™¬t^U©TckCs}GjsLe]FYJtkOrfLgkMsXKrVFLdE_O1q^>RuTwh8SrK]q7Wp3_k5Tt=[h/‚¯Z{ÙŠX§e‰aD£‡Z]ŠRJo,bc/Tq2Tx.|o8sWƒ¢XÉuÌ—u¡inžw¡ƒS¨¡\°˜WǧnŸ¥pˆ™_„KxƒHuG‡`>š‡`{§gkBsœN\”Keˆ?v’YbxJAA+B9(AL::X1CB5OƒOEœWNŠZt›[¢œ\¯¹jÛ†™»c­»j”Årq½a‰’Ks‚CZ[/[t;`UHqVxFa‡Ps \™¾sžðvxÉ_uˆInm:RS,UG,]]9spIQwD’~Yx°jU~Dc€F{«pœÑž›ß£’¾}†ži„|P[X7_L0>K'CG%Z\8OY8r‹nwks8`k4Yp;tr9‡’HOi6bF1b\;\Z-Q_7~}\­Ò‘£äŒ®ÙŒ²è—¶éŸ‡ÔŠ€šp–£uš–p¡’u·¸‘®Þ“À좾뛙ºvlœilŒWhSqzT`zEcpNiƒcg‘ZdŒWˆ¨o“­s‡¥e}‰Tx@il6Ka1Ub8mzE|‹[t‰^{jxžZmŒH~F­˜a £pym“fš˜ew—S{‘SƒTwM{—V§`‘°f›•Yw…GuQ‰‘a€™eƒ¤o‚®tƒ¹{†°s…¤TtŒQ{K}ƒW¹ †½Á©’Í—£Å•À}ĉÍÿŸÊö€†¸\ƒ£a§œaŸ¡Ws”Ic„BS{Ei}Jwz@hy@[}Fd|;UpIQ1GN,GL,OS5[X7PX6W_Ce€CRy3Op-Nf6b|B`y;K\0KV+E^8MsFV~EXv=ZiC\}Soƒb„¤p§¼vš¿{¦Ò §ñ›ƒÛuV«G@x:3XQ7k\=>]@;E457`7 Zg0a|G}}K‚¡]„º{K¾Žh„ypK]œVi~a…dKeuSPQVYLCCP;?K7ZE:jX6HTFOBAPR5EaCKN:O[@S[4g-¬Š<±_O†q^a`aEUR;NEOG6UY=fU7LxETsCei9JN;CM8ZM4†e1l—VG|u-IDB-![D$Pn8-_AF3/QF$MX8?O43I,8?&?E!UY1hr:c|@VvOUlHKcF"9R2JP,Bn*%X186HZ#ov/bšNDsT>_47Q/CR3V`3UO/]_5Q{MBtDP_/fb@zwLixLe“Qo[GŽQBV9=U(MT-ThAKk;Zf0Sr7p{2yy6q†F¡¨Yµô•ëiÚ…`žb[œJ^uKc~F_„NCk?@I+^e6††C¢`}³fyŸWj’\lpMƒ‹J{›\ЉHªN¯—]yÉo¿ƒS¯©g‘\¹štÔ©—…œ|]Ë”]“WŽmM¥sR­^}mJvr?zCƒ„R•~^lyS•uN——d¦vrœu~‚dk}W]qERR3fsOh‚mgoOsINwDHb-Rn5^v>e…=ž¶_¨Ã{~œ\Œ}LsaddWŠRc¡`\‘Pfu,u~C„ŠXvºn¢I·‘bÀÀ†žÿ·kÓ—‚\x‡S sDpB‡h?rkHŒyN„„Wq}O”vD‘ƒTijIr‹NZ€\l>erNu‚M|ŒVZ–“ZkNS|Hj‡Pš–m—˜k˜¨rœºgp¥XZ7`s:n‹W}ªc®nš«n«©k“bu‹^}›juœkxaœm’²ƒŽ¿s„¦UnŽJl~OlrO|ˆoð­´þÛÁ°â™¤Â‰°ÇŽÏ쩼î€Òmw±f‚¢`}YqšPt•UvˆSpxEptBYzDb„Kb‚9Yp@Yk@e_@LV?PaGcxPd‚CXa:S^1LM-?:.>F+BJ*L[9btHb„EXt2Eh9Wp>`;Qm@Tl:IpDYzPj”PbˆGVwHZnCfoL|‡e³€œÑ‹ãŸ¯ðš´Ý}‹±VušTc‰=K[2NW6Uk@LbESqjƒŸ”¨¹¡©Èœ•¹Š­oxŽRip;[XAgg[zžv‡¨lsˆgsŒecˆcm]o‹Qav@^o1nV:`cCNgRb[LLYEaSD`y=D[@MP6Q`Bxd9X•[8`n+:753&MN*D]7D]8ER8EL..C/87/5G&;Q(ST+ek6P‚GKkJKb<stLJXYVHWl3\tCh„GlŠHUˆ[PU=Ak4I?,|M)L¦ELoaXX.9‰75g>966G&FG'Sf)'R-77#DTey3dˆAT§\P˜j[¨q^¨wF—oBtYeZ@_…NjzU¬z6“rS{T=joA”[mn]…RNm@LrB_m:OtLCoGTY7`k<^x7U†5`~9¢LË´lŒÿ¤¤Ž`}ÖpZµtnqI{œUVŒYByQOF0NN/TI,oX:}‡D‰y?˜Pq¹hŠšPs‹I{D•dššhŽÔtš‡U­—c­p‹›h®…K—“\¦oJ…‚W{‹^‡yHŸƒQ†jg|O\ƒIs‚N•}P—žlŽžf–›f³šo¹§~’špŒp|”k[TNdlGs•X—]{¢U]x7xr8†œ_p†V‘ž`¡É…f¶oW…=f}Bna;¡kQ•dSX4vZ6ÍpD¯’a}†V€©pƒ§kis?cl8{sK‚‹T›Œ]‹§zv¨d“´n_’dY_2IG(Yq1‹ŠYn€dh^Rl`RyeP’bT~hG¥ŒK…V‰„N”—h‰­s~žQ‰~Hˆ¸pºì‹¬Õws}Get‚³o“ß~©Ç]b¡GGB#LE&IAf=%zn:c<‘[ˆ]Ÿ¢Yœºk§ÎyŽÓrgmRZvYw…Y•‰S_|Ac|Ah|D[q=Vz@Vh2`_#fc)bh*hz7z¡Mv¬W^P\ŒFjQU~AocK¤…p™a¯lB—=CL(OE/iS;œU1™n>PN-QG4CP5:E$L@,|O=”]¢¿w°á€Õô¦œÖ‡—šf”¼y¶tÂ|žÇ…Ê„²ÖžÏíµÙÿ¾Þú·Çù¢‹ÓŠ{³“оŸ¿”žÂ€“«n” Rou@muLcxMmlN€}^Šœ[z‘SˆT…Pl…Kr“M`…;Vj4apCm…XŸ¤l¤j–‘o—¸p‰¥`vN`‰D\~R†¨d‰³^˜™^¤—\šœ_‚™`w g|›_s™c‡¢g—¬uŸ´h°m…§dw—VrvM}yf—ªy믋턤»–½ož¸p¹Ð~´ê™çs{¼oq¬lmž[ƒX~Igq8Vc;arPhƒRa„OcŒYV~KOk@V^FfmUqWhˆHfiA`b:RL8LF6NL1LZ.Oi5UsHu†Ri‹MU{Dc{Dh€IixNm}Jq„G^‚N\~F\{9]p@SvH]‚Si™d­v—Ę΃«Ñ{”®]q~@\w?`}:Vf3W[:d_;g`Enxd‰”jŸ^ zZ„_‰XswGc_UfGeWzŒ`{…`{‘n€¢sˆ¥i|›OYi9P_>YeGgyX`yWbxF^\0QM.EH¡’zV[RERaKjW>nk@‚~bx’f}‹y}|i[€`Wq]QXLI`DSXAMJ=LL>ENDEW;QV.Il-:P241%?#'Z,iD+w-*€D/GZ>HQJKJ4VQ2dk:dZ9f^B‡yVZ¤fM_rRE9^K4Rp=QZE`b8LiD;X=4A+5B/DD)FW2Ad7ZY0Lc0Bh>TR4T]17h=.Z<3@#@>\]$^~5lŒHf€HH—N]nJ[_AU;IP39U-;L-QJ Zr>TvPHoLHSBhO(gv?kƒ[V‘P:zXn51[.:R'UM%Ta$NwBPtGC_55Q'DI'[^-ovE\‚HUzLMm4?g::X25Q(=HMOjX+av9He7Ac:m`/U’?9_ECU%@\$JS&3a*3A7657K?!He$@R)5\=KY+g‚;m…@v|=r{P{l?ƒj@šrN–®fˆã‘wî¦\ºš‚|RKU7G5!fS-~uEt„[r¢{uŸkg”_d’QfP]€HVq;Ok9Up5Yx4vˆB„²i¥{P£¼bb•z’z3¤OfÅ}‹ˆ[r—RešbJ“d_‘We‘YfŒY_‘HL{:}m7r|F|AtžM”®[“­l‚PŒ¶cˆ‡W¯œf‰¶o{_Š{H‰’XƒvJ­§j¥¢…—nÄV‰†ozyS£_} t•šnª|•§x˜b³‹mÅš‚—®–‹—y’wl”{QpfW:NT>Kg>Nh.[x1Z€:_0=h8/b5?O/cwIZ}B€ŸcÑyo¾cŠÁi›æ‡Ünj…L›nX–ky¡WeEn’Os‹LZmgb4P\4Q`Cc{X}ŠY…‡U…z[oxRd}YOvLQlIfyGgx@gX9`U6^h=^c@do=Rs@\ŠDcŽN|ŠQƒ„N}vAvt>ep[t:jb6hgi[_\8DY>ZR9la3LbH@PNXU9Ef4X`7)R.878DG))U4H,-YF+eE6ZT>\\6WqEZlHyk:}];˜—\b“qO]`eF=^b>ZvH\^CMV:HTAGU:Ia8M\=SU8Lb;DW@Nj9>u=/T7NE%UT!Ec64X;+F0DP$Tb/pg5b“=VKe_,V6KtFDa:DC/@< 2K26P&TJUh4LpNCYHDW7ZL,]l/n~HqŽL4›]CJ:@Z%0Y3V=%tc"C¨aClH^[(m;v§[m¥dw±pz¶o†º}a¬z\wVfy8r}=Y“XEI5k>%oe,c­nDƒTDk@W€F=rPTV5Tk6Dd7A^9@Y)6d0=D,8N#;]+JS+Yb+Lu;4k97K2;R"Y^0RˆIS…PSwMJy8-mY5V9ŽuEr}OczIXiIMd<5H,=9"@URq.Vw9„J\›eUY3·j-R¹aU{>os-‡BÈn‡…_€Hбn•¯ui„^]cDdxEcHygEY‚C^q9dt5s4œˆD‹¿f‹Ó~—§a´•YšiPioM–~B•‡L†˜^ÏŸl®ŒY˜x\¾‡T u‰xK¨Œ\¤›r•v™—sŠ˜d}†N™qPÉ}e´¢y~ y ‰c¤kksWPO2[hBb€aOŒ]]vEO…M8R+71G]3KY2T[4FZ+^x0`ŒG]’QSo8LS4[h4m}7€p.``A¢ƒ_ƒÇš]}dMl8Ti5„ kš´o±jx–QÔža‹³krŽN…ˆQº·€øÿ½Žá’Ž˜^mê–ašde~Ol›^€ŒOˆ~@›‰HŸ¤cƒw`yiY„lR€ŸV‚‰]u›fd˜YR]e›_ˆ³l˜”aŠ£rUuGWD#s9'`a7^s@‰rM†^pšE€WŠ‚bgdt |YÈh«cc”X‰–a©·rž¿{¨ê‘²à}¢\š‰^“‹i –g›£_dˆOuYj‚UGa5TU6J\?>J*^…Y`ÀyO~>Wp:„¶q™á‰e¯fdIW}EjwVtxQZX?cJ5mK8[RBiWBxU@HL4HG8ªZKiŽRBP->G';<"MH+cX=nhJy‘V£¢yËÞ›¢ÄtuˆTe€Aq|I{ŠVt¡v‰Ô¹×ÿÞþÿéïÿÎÑõ¦·Î†—Up|Nm{MYd>YZG{}X|KoQÀ{n‹‡i‘mR›~^•‘Y‹sNxsFk}EhnBjZ>c^;Wi?Re:bnIŸi¢£u}PyˆJ‰XmŒNdy9dp2n€A…‹HƒŽS”˜_–™cŸb²dŽÄr§Út•Ãf•¯fž^„—Z}ƒYˆŽ_¨m‘©dƒŸW‹PzžQ‡«f¥Æf{¦TŠ™išÃˆ´Ë•¸ÌŸ§Pjw6Qb5HY=RaOo{U}‚PlwKjj?]]Ihvmyšvp—ciƒTYyEOiAF]?S_Iky\z `q§Wt¬Xn¡P}t?kc9XY:\m@XkC`jUnyW`sFt€VnJVw@YGjŠGm~Nnƒ^Œ§d…ž_l€@dh6U[9dcHolWszOg‹Ig†Hq„GvŽV„…K€z9VW-;N24U4:Y4K];UZ3VN2`U3hZ5fg@f€TwXmLbtIekGWjDQc:X`@YaFbmPm}OxNhzE`e1:D=JI2TN0aN3n^:bfKRZMI_DlZMYTAFRFDKACU5Z^8ie4JzE/`IšA2w†2s«_™mm¨ibucHdULUJMQDRPFUQ=U]BA]FFS@\E4_P0SeE:YHJFBB[3ma2E^-ZT;Qb;>[LU14\G1NxD\^Jmg=[nOU[N}`<Ÿr>vœ`N}r]WGb`i7DW*LV+HQ*Ac6G~JKjF=Y<^M7fo6=–MHZAkQ"N“;2tOBL8JF%hH@O6PE+>f3T1`a,[‰JiŒONŽgKpELj4B]8>X48K1;GCL#^g)NŠ9AsBQj3Us0R{=Mh6=h?9O)8G&;Q"+L(0?!;=R\$Oo3Xr9]‡GRANk-QL)hq.AzKDZ2`Q,†T,cS8xT.fOAÁB$«±jdÿÆH™…GL4BF3MB,vi;s‘QRbDa?7U.;J#J`)]|6\=y„FFlO6K*K%fEL~LKg+df-„s1m¯[jzV’g?†Æzkro|Ll’ZYwBbv¤•[Š¢eiEn€Lp‹_†¢e‘}YŽ‚\wvQ~iF¤yjy’olTehVekTÈŽlLRLaFN|HZzClzFlvN…¡e¡»~ÇÛšªÖ}¤hf’Yq™r”¾–²è³ÎöÀãÿÀïÿÏÞÿÏÅÿ½£è‹‡§`n~JcsMgiJo‡a‡“juˆdr‰\xt]p`’z\|a£{^”‰cpZb~L`cFVV@XK=YP?eeKitKr€a®’l”Wx}FqtD|TfW^ŽId”Zš[‰N|oNšTs„=r‹F“ªeºlu¤VbEn}Tj”ZOr:RS4klM}XlŠ@knIQ7>V3IL7[T(Lf.'e6H>(E z…?{™fTŠfR^Q\T:fc@IkEP`GaW9Q`@IiEBhEO[>Vb9ne:[oCFcILR6LU5[I0_K2N^<6nAHG5‡D2\s=[€Ym`;VfJZf[quKŠNhƒTYr`t]IzzD_x\SWOQWBEkDS[K`YA^U`1DU1:V05K$XM!xa&hHDœ[EjQAVGa@0Q{+:K_S7ka,L‡BEuFmL58gB6HAIIH_3^\7RŽDFŒaGTMRV+Eg9m\8Z€:U~Q=uC;[ELW.lqAdŸOq¨l‰¹j†¯„†•lx•U{‹O¥V…£i’›pV–hIj]Xl%A};*h8EA0e_*i{J>ŠXDW?H['1[@1A&CHIN0@l/La3NZ(@Z:;`9?\.BZ/8_/@`0N_(mˆLKŽ[IcGKm78X11J%*=.9=>NW"hf,KPGl0\g/Gx;PV(KL$6Y,8A!AO"5L%-G*><XW$Or2^h,i€BQŒHAq3ES&b[&Tt:J`37L%97?*€G'9TW2ZP*oŽEX…TRnGVk?kb1p–[j­e[›RKl1PU#\Y%lrCWzEIq8Rj){v>©fF—go„\_h5—o7nŠS`}MŽShoB|e='ONZs@aaCriDrm@YoGn†Nk>aufnM~JZtR]‹dgš„©q†™SmKtWy–htŸ][€Ia10I%5C)EV:UhHa|O]ƒCUc4K\5Q`;Zj9lg=_Q0FS5CP4iSASfmJOyIrW?ª[3YŒ_klmuHc}Th…Rˆ†V‰„\X‡hX^_pS?ŽZ9~iJt~P`‚US‡\dyPgŒN@zRGN;?O%EH.:F*6M.JH!OOfS'ty0d¤O-†pDMLgZ1PŠEK~LZT0iP'Yv3u‹J=kD9TESU#Ea>WN3nn7O–]@vbGS2Nl6Hk^p:^pKB{G3W^6`)>lNWl4Gs3Ve/e‡GM‘EGw0=^/LQ&SV#Po19iE5O(DM)q_5BS???$A9"h2À@ˆÀrbâµc‚XoˆG‰”Vc{UYsGGhEZj:]rub)Ea"Y^.Wc@QnAXyRk8Ib=OgBGf5?X1A^CGoHZxM[rHXj9M^5Q^9\k=bl?dY5LU.PF6bG23O8A=6MA,VF2LG>NPGUO:`L6pV1o[6EM93K9:R7CU1*M-WB#~[%‚…DŠœ_[°ev–fMYH`[:QDTG?0N4?84J@,UA./J;A)-=#:+":+ J.ZD,KO5[O2^f7ae>koCy‚IX‰KHsRc^A´q.d„RcqledBbi?}h:ˆ}L˜—Wl›bfŠsZdZ_YLjqIkzLk‰Pn†\cvTPyN?VF;N5>>.@=#??&1@$7>%1?DD#iF!yc&R¥VSv^hqNo€UE—XFf@MR0lI*q†;D™YIp?Xh:gv:_ƒ`2bZAQ8HZ-6l0-K*67AB >F/2A)9I':J#ND Pw1DyDQj‘S7ZFSR*_‰IS(¡T2‘³_e¿Ÿ€qHd•SLV;X_,Sk8\ŒUdˆUhi;Ug4cY1O?_j=Pl8Sn4V|3Kq2@X&=8IU,HP;vO-n¤M~‹G‚•LqÆfŒ_Yf6jt;{:u˜GŒA˜yU‚xeƒŠSužUª—Y„˜kwŸN‘ž\›q†‚[ŽrN¥uOÞlPÃ~I±¨lÚ¡“½‹¿uWœn:wuFŒ…ež†j¬‡o®†f“vi„Y^w>^a?]d1iuYN3`~=X0>TC\t\q‰k€¡‡ƒ«}o—\g~ISlRd:[h7^d<_X/D8)]7(CK/9FIO=@F5ZE1TH4nS6XW4T=-E./>&D:WJb`2zjB’ƒO{­[n¦g`oCTSKH=DI+`G4EH6_A3&L8'.-*">!m4JQ0KO:ND)DU+OW3Ye4Ss>V[>LT5ie@ws2btH@THKS7e[/„`,zb=~fT”X‰hr“mo‚`d–]e‹^rvO^~[jwVPmGMUK7W>9L:0G/1C-6:%9;&6@'7F*:K0w>$w|2vzWu•Ucua]|OHŽDB`@TN1mr0ZŠS<’RAZE9\9FUIT4Rd3Re2brCI{LZ_AKv9V^6{e3h|IgˆQN”^B{bAf<,h45;"!]D!Wƒ4M„KCk>i_7SNLUF_CDW.7_*#WJ*+_<\m1Jk;_f-M1O_>Lt3Nr8¬S*ˆwDN~w?l@KoCXy@`„Nd†<[ƒJe‚EP‚CYx?F„6Ek0IW/Y^2al>ax>|nM[pFalEq]:VTnwQ‰ªh¬¸dÿÀm±¼jm´dnCœz@³w[½™x¢„_ö‡i¤Ì ‡‘o}’_Ws9eZCm_A[]=bQ.Vi1@j-RT&pxYv=ChDBa7>\,Lj/mi7nnAivAs•\Šˆ__£©nÒñ¬àÿÓÖÿË©ÿ¹€ÝŒeÉpr¶`qÆgi«PP¡GBw.HSˆX*el0Fh3jn.y†=z–@i|D~ŽIb“Mf}DLj9`L*|}>’Pg8TO/W]7UT.`P)ˆ_9siE;SGd†j‘Æž…á°ƒÙ³ˆÍœ Íˆ•Å}~°g}¯]—N¡¡S§®m²Âp¸]ŽWŒ¤`ŠŒP–vT‡\ŽŽj’±v·Ó…Êñ´¼ÿµŠâµ°s°¸q££_…`H›b=¢Q|^_mQ}lO‘iƒ±dŸ„\«qÈ›xë vÛµ†Ò­ˆÊ¦|«¥n­£m¡Ž^”‚QžŽT¥•i}‡ZbrMYb?ga=_T7VV?]pUp¦~®â¤Òÿ£¥Í€•ž]‡ƒPš¥l“¾ƒ˜À…–Ó”tÍ_žko¥qŒÆ‚y¤YsgK¤«ƒ¾t\pCn‡S¥Äw»éx‹µZwChŠJs—Q•½k€±g•¨x‹Ëƒ|„y¬~†±„™Ä¨Ô¡ªÂ•­Ä‚£·u‡–VŠ„N{{Kƒƒ[z›^^F^f3``6X\2S[1M\)IR.oe:x„;Zw6Fj+Ee,9['=Q&La0\{E”_™™m“¤`¡i—PVv;4E21E-/N,*J+4;"OES[,`k;}pF‰‹Kq«[@›k6JR?97O?&PS1L?2<2*5+&1,;.16"i6mB PJ)HE/CI$EW*S{5JsAI&9Y4kC+_n6}dMq<] f`t\bDQ„EXT8`m=]|Y`pLR“RIpKQl?SLlwKVƒEG~H;b5JW2nj3~…7o³tTŽk>wB?TU}@tZ0Ÿo5T~ZR^<\R2Zn3Qk4`i/Ts6\~CRbBWu2RŒ8Q]/Ck;I^6[i;rg8rb4V`CZYAQY3JT1ZS8nO7o`;bbD„U;z¨[zƒVq˜]i‡Ad”Da—TƒJoŠ]qmPe‘Ye€b[qK‡b6MŒTPk8_t2„…:IÃKuSWxI]uFgp:Wx:oz@jŽN}†We›_P‘Vqo7j>Qo:a[2xi>‹WƒŒZ_šUzgGoNWyHj`IsmRps\q‹cˆ–e›•\Ž’S—yOfw€Iny1or?}†Rº”G¯›]ŠYÂ^¤_t‘[m½…m¦{xn:mo=]n3B_6J_1I`=I`2is7fƒG[bCccF‰uNj’QUu=PQ=Qo:Sw@NuPS{H[u@dwH†‚StœcgmI–}>ÕÂãð¸ÜÿÊÈö¸•¨rˆ¤bŸÈl³òø‡Ž¢\Zœ^<„@Jk5Fr5Rf0_\-]M€žl{kI}qEud_nAYK%YB"}l=|Lj{P`aGedAMp6AT4^lBcqJ†lªÁ“¿ß£Äò°Òê¦Å豤߰‘Ï–~¿‡ubo^=‹iR}]Ž´j|µh{±l–¾tm£_’yWŸ}b°z\ª’i•©xɺÃꡲöŸ…¸jªšZ¡˜gŒmx{WŒ†d’‡j“q¤w¥s´¤q޾tÈfÊ›h„SÈ‚b¾”n»j°˜c˜\’“OƒšG‡‹K˜‹a¦¢`„zKwn=\`=dY>vsP°‚¹çªÌÿ¸Ã觇¦nf€Ra‚a‰«†Ú ¢Ú°½è¹ºöÚퟙӇ¡Êwž]EfEybZªËŒX¥_dƒT¥¸{§ÌnƒžBlm:r„L{µn‚¿}”ÇŽ–Ж©×Ÿ•ÅŽ¶‚”¸ˆ¡Ã•¯¼ŒŒ¥v˜œl‘£ar~Avf?vi;gjH‚‹Wk–LRn=GZ6^N6YV9N^5Ei5Sn6w9r‰6^u0Nn1Mf)=T)>J%OP,_YLX.?J->D%=?$6F*R;!kM&nR+‰S9NY?bHEMP?>H@Q;1MF,VQ/WR6=U?LU?CI6?S0>Z0$[.B='PMOb/Lh:XpBˆr>‘KK¢]+i\:I;OM1;S6(I2,3&*/*9(> +4$1:#7A"1`.2K/KI!}U(r‹5/ŽP<9=-D(@?+5Y(Ia4An7Ua3;N/KU6hq2ƒE…|Sqh—w_Šp@v ii—nh’^sŒWmˆPn‰YfyQ]rLPe>?N=9A.E?+_?&6M3:G?Jc6Hs:|fBV~EZg\ud9gMQ•gbuSZ‡M\~IcrG_†MrvSc€LV¡]k€M]žZcs^ON‚EBfERc<`r=}r;k²^U›mQbB:m4ZK5sv0M—`l^Jre>d_gˆpc‘ev’g“_x¿1‡}6JF=P)GY#Lb3Mi:Ce:XnF\ŒINƒQSnE[rBTwTpU:{m0rŽNOmUO~I<|D6N=>R1ES3AK+IU5Pk9Q\:nL0`AXŽ]eƒD@„H9T7O\&Gq8RQ'TuDMƒjIf9Ma&4;MFMj)VX0\j3LvB=P4RR&V~0O‚1JjAVb@Wu=8jIU<'\N0Nq>?XETC)q]-hgDghETQ7‚K1gŸ_‡“\i©\l‹T~¤RºuŽË›y´‰a‡XqrEss@mŽTwzT[ƒ2Qk/Xv2¤7’¶i|}WopEa5Tn1Sl<[kEƒxFv“ZuŠGg¤O_›RZƒDR{Fb{G‡“_|¡k€²msžb|“SmšN|‘O‚‰PŒT€‹P…ŽYrU‡b>Ši3se9€g2dv6Xu6vc4`h7uoB•V|ªjv‘@s~?{`D­tOprKbnTZ4_i.Yl@[€?XB_sAi{Jw~Q\€Gbw;‚M³‚Pʨt¤Å‹vy\y~D˜y?¶¤W¯Êzo¸tiXAoJ>W|H_ŠCešQW«d™‡m©¨xrqL^F4yvUVzTGg<V`RZ<:[;.F3)?$5E#Hl.=};IC;=O7aP1Gb2:T5?P'KG$PR%+iE&y[;\m@hƒO`NSxM–Q4iŠBRxkfVBnf:kqB_¢^_w_TŠJWd;`i:jzQh„Vtœgw®nvŸgR™eXcRPe7T}H^BSYHvj:{ LX¨nAdNEG,Hj0sg4R¦Z`wV‹€X—™|™£ƒ€™„Žl›–n ¥suÄ@ŒCoURr;U‡Fa‚JbˆMvŽWi”_QMP\8V]68oK5E/V>kJS‡Dt|Ur™Ec‡ZOˆVBsaGQDXd=5S7-.#?2jBpx2a£_>U;b>UW&De*fU.’h5V|FzZEa'@fd^"~w8f¢T^“M=v>> 5`:/B+77MN%Cd)E^1Yl1@q>@M4PO%[‡0qˆDr¶j`¾}j›l\œ^U—b\``Ÿ`Iˆ^_cN`yN[‚N`sGUm=eM=u:|¨u´so±q’¤l×´wÕµwv~knoC_ŒKdwBkwEa‹VU†PW{-Sz9{z2cœJDb>Qd$Zf.Uk>TxQOXFz}@€„Rh‰Nt”EE´oh¥kƒœ`’ì§“ô¸Œõ´fÆsLr’Fb¥RhYgPejA\bAmjBhpJf~B`yHa€TZyDnj2i|M’…`³°ˆÉ®u‚©na‡StŒdhmU\hEbs>Ne?US-La&TI0hVAZbCnf8eŸ?qvA^lAdxJj‰VX}I`b0IZ/BU/O_*pi-g€=cy>^iS‚?Dh6E]5`wSSuIYK0fB,dW1…z6®Ÿe¹È†´Ù’­Ö‰žÇƒ›¸Š‚¼l_€C^_3`h:ŒgC–¨r²qŒ±d…©\z–X€zS¹™aÖÆ€‹¸mnzMsM1d=†tF†‰T„“]•”b—¯vtS•‚Q†Yvm™¦‡š·‡x£v“šn™³ˆ‘À•‰µzž¤j–šg²®h¹Ãt–YhyP‰€QŸŽR´™ZÓ“\Ëšbˆ`•Ÿf¡žp©Ã¬Ô‡˜¾o—•g¶˜r¡Àz‰«q€¤mg—Z`ŠCX}E{W˜¼y£±w´²‡ËלÆå–¹×–«Ý‰¢Ôz¡Ôƒ[²[R`6€uLq™R|™>d‰4Mh,LV'RQ6zˆ[°n»†­ÎŽµÏ¤Ón®D`‚>‚kQƒ]iwAYW0u_?zlBvmCir:Yf3U`5%E=,IL4RP=WuXi¨ˆ{‹•‰¯`d—Ih€[ˆ¨m}­qf©mo uްwˆµcsœKn‰;q„G)>C+4>*.4%#A(!9%$6;:T>#A=!(6#=13AM=%PI&CZ/RY8VP8/D8!.-E%"'K*G*$9 *1-6 O= UV.Qe7a_>/mD>K4IL,4L.*I2CC)pL%r7V‹OLoJM^7>d.VH"=M&5S;SB(Z^(LoA9fP7P-RC$DY,FWBFT/Sd/\u3M|?QgAVW/tc2bn3WtIhm?g…@V„W]rI[_9ckDm{Ib‹KIuKIR@9U8a@)uXut4j{AStEc^6Gˆ=…YBf3C€]ZNKOX;oJ>lo>W¡VZˆ`^ŒNcl:f{O—g‡¸|w·Šb­„N›dQqJbi6\‹FU„SDƒ]k[?{˜Gb qBBFF4[T(u:^¤Og‰^etMjgHbf@\T;ZO0‚k9‰¯]–Un«Pq£sw©[n˜ZbˆTauB`c=Oe:E_5LM#Q[/:vI-R2.C)A;"h>!g‡;†™_©[ŽyMpuG\tV5wQ?;%/21;=jF"n€5I™YBhGBf8>R.TP!‹e0Y|^HiFGuCOm-wj!hj1v…Dk›KBŠGoK4Ee>4T@GF)MZ&I[-OQ/]t=;iC8M3VW({6«œ[œµuЬs|žgy–Z‰ŽMŽ£fˆ¸s‚¿uо…‚¿†ÁˆuГ‡Î‰nÄ““©{™¸{𷉆Ÿm~˜_Œ…NtmFRd3c_8htDd{Do‰JrŽSXRa€9W~0p~6h«UL†KKg7Yo:kt?ezRcuQvŒTzƒO{¥Vl“E„‡M¢™dq§pž{äÿ¿ÓÿܸÿˉÙnÑ|n‹Ptˆ9d9bq=l|MpŽXr…KŒ{FxtFŽr9—yLa†G†SœÊ†õ«tÔ±oŸ™`ˆŽS…˜k‚YhcAZ[1^Y&ZY&C^4O_3h_*r^=`^4]a8pi@i¬P–ŽYrlŽkJX{HB]1AU)CO&GE"Va.SY)TY7Xd>W^6LU.=P"M_'Tv@Wm>XbAdlKi}POw?XTEpUo“a]QT|;Js2Zp;_ˆP`”K`>Zt2X|Hs[rŒU]9Oe3P^;ZjIs’^¯VgŽIUzIn\yŒdtŒeqpt—ƒv›qYzLXzKd‘du­k†»c}¦MwLpŠMzOiŒTh_n]g}KhvMdpEpoD™sNª†SŠŒTrP`€PP}HV}MZ|A`Df}W…–_~–\{]˜ŠHoy:Lj3Ql:]y:Uv@RzHa{Xu•jŠ r„¡srnXƒZStJ:`A6M85S?7VB:V0&B*&A#*;#D81++K4-G%9A-J6 Z?'PR/D_4;L7&=.E/(/U*)J3*;"+?/;!9B$JM%JY5E`<:[<6Z8GB7L3'8P)HI-WY(_l1Os;@b85K'8Ik:JD,>X>JD2mG#J_27iG9Z2HU!8S*3I6AK+V])Sb-Bc3B`@E`5QV.]\0N]/hnXN+yq0l¦KWžbFƒdAlM2Z<)J4L5)}m2a­Xij…‚?e¤IZyeTu6Vse„H`z]y'{‚2r³]]Phl-S…I_h>eq>o‚Lf€OrCgƒDŠD•·p{c§pâÙœêÿÕäÿß¿ÿÁ”¼€…—\_ƒE`x6b}2U„Ay€TŒ—ahškixMgj<`r:zr4`†UÿwHÄÁ‹Œ¨zmUszMwpGnyPKeET^@VhB@n;Hb4Wm˜–Q“§ot€_riLa]=CN(E>!`C$w\0–z7•…Fl Wk|IsœWh–Pt‡U©¬w‹®_Z„Bhr>z{KyŠZa¡Z^f/F]-D^2VV1W`>}i:r=^|4Ur8Yq@gr@rn>wH§¢r›Ï‘‡Æ‹„µts•Uf…K{ŒY°s‘œa~ŽWpMž“h¯¿{¿ÑŠÈΜÍ÷ Ú}¡ f‹ƒRlrAB>%D/S9#EE&04O<:Œ«v°Üšçÿ±Þÿ¥Âü…»a—¥^€„Jte?psWzX€‰]v“Y{“UsŽQ~‹OlzAgh5^c*q„C’±R©Ìb£Ñc‰ÁYwIv¡Gf¢MxŸXŠ«_’ WŽKˆƒN‹|J~ŠQzSy‡Zza|l‘ i}¥ZˆŸZdStŽw{£xeŽVLq>evR}ži¸}•¬€žÉ“²Ô‡¦¶fy‡:Sb5arIm‹RhŽ\ˆ{¤ÄŒ©Äs{”JWZ0X\)Rk1Li,Ji*\h4^o5^t;Qr=XzH_…\g~Qd|ELk86b7HjDp’YyVZrALi;VlHblRhfiˆpy“t}šrh‘c`—e‚­e„«RyŽAms4Tf.IQ+U^1ZwLt¥xµuŽŒ]vxO\yK\vF_tJjzK{|K…xGp|R‚™_z“Kes>Yl8YjGxzY… a€¦Pey6Oa/Jl3Jp6Jd.RP1^Y9UbKZoUi}`sˆlvŒqp’|s£wr—kU\Rt]UwWXrH+>%,:%3?"D7%0:) 7@0E'>@"9221O5&QF3WU68Z=_L:1d:2Q<3>%1G#1K(FD)Q_8IqK?eMHT>2b4!K-E(&DA!@H*IM)Mc*;T+/J%V-FX-Ta&Bd…QKm=LX25P4=M(P>#DN%BY3QG*ŒD(ha2W_]^H7wQ3RDDS,qžLuŸkˆœTŒ³jmŸ~|j… hi«P›tB†ZfZ6~y2zBo¹]†¥mAÀuTQK9w3UV3q{7{”Xa_O…bEzRDnG?jDVfAr~@£_WÀicuUzm*JœNRsVLl/Fn9YV8Nj4An2Ea)Kb22n=+M95;<<C?!\Z'o~;m”JQ’LMmF=U4h=*E&}_4ZiLJbANs?>g;<[4DP3]Q&o`4fsF||RPYA`JNZaq"c‘CXlHsG-fe/tŠ>}i2=&oF(ZG'S_(mT)kv9fGj{JVqN\sAow9hƒ=]cAPW2^l1[€Ars@™i+‚–Ks·cmŠX‡ŒOš«d…˜pj|XyoBŒj<}~D—†Dl‹J}G–½mV­|lr;w„C|‘_ˆ—glhd{VfvH^†HR†;wv7o°OR—UUvD}sAZ•O^uIenAlv;e?_u;³ŒJâ§vã›ÈÖ¢ïÿÆùÿÜçÿÔ©ÿÏoªzp€DZ€BKp2V`!mw9sU €S€~UfgBec9Zp6l{:{q:‹‹aš—aznO†pCŠ„]lantMiY:wrIi‚P[‹bhtUs_nXn›[lž[}©kd‡[waGm{‘_}©S_sIHe@Qg@OjGKoHRk>X[84c*@? HU$HJ%LF*?@(GJ$FL)e@)hA0QeI[Pp:BS,K^7Bb5HX'IQ&O_+Lj*D[7J]@LgCBpG?rC`wP—•m£¾}‘«_u€C_o;wzV·²x¡µt‘©vºzŸÂ‚­°r­•gÀ¶˜äù¿±æ ±È}Š¥addBKR34>*7D(DS48Y1/<%}KA¬•[Ç«gÏÄqª½_j…AmlM]–WJtAŒvVŒ‰]tKbIryE~ˆcˆ‘]ˆ`\uKKP*DD#hP0Œ‡Rž»gËjt³WižEp’KjŒJs…QŒZu‰Tv…Uƒšl‰§hЦn‡t„¤zƒµŠÄ“’Æ‚‹²l„Xg‡QzŽcq‡YeˆDW†?]‚Mœvº’“¸’™¬†–¨v`RfeFjgCsxK—^ޏp‘ÁqЍ_tKS}Qj?XmE2aH4S:=B(:Z%>T3g^5UQDkaE]KZ>5RH2I[5NL)LT.?G+>L'1S"/D 6EFK^@$TV6^bAFqD@^Ks>=i8FF*;K"PS*]\)ZvDUdADb@Wa5Rw5SrBSm6L`;?d3Ha7Ub6`p1J11S2;T6drAVUiuJ`†FTeDOT.GB,^?(oK&Ib8QO&Qi3EV+IV%3V0HB*‚S+gqDx~TV„WAhN\i7j†3m};?rK9?7U=_n*=w5Q6&>D$:?"FX#o].i…KcqKflER‚GNqHepDV†CJg;Hf=^n=W‡GT}Dc~Hzs>s˜C_Zgl"@R*\qGf|M]†TRyDHd6G`7HX0RY)Jk35[(?V/Dg,:Z1F^abKk{fn˜noª_`NnˆQ|•TrŠZV|D<^.BV)@K 8J'@]):V&6N"CU,Qh?i…`Ž®‡·å­ÒÿµÁöŽÏiy«Tg X]‘WL{>6Y&.9:;)WN;ssKqEoƒB{}Age3HM&2G"1D EL"HM%-C"6X7_„a­rˆ`qˆ\oyRmqDggQeˆ‡Zp|FYa5Ug4eg+Gc$>\*>b/Fc9J_6NX0;K4FR6E0:A-6/66.7!+7!$A;$#6,1377A ^H&VV/G\?VRHVQ=|S?NjE9kL7W@KK1E_2joAfJ?j]I?E7V2)B7F4/KS+Ka3jW9>`?4Q<8F+7F#O?%ST(F@.DH65Y(6K*2D ABuR%Zr8J`DH^;Tb:RuEOl@Hg1Y\6Up3ax;Zv?Z~@s‡>~‘Wl™b>ŠcME@Ui.Mr>9h;;K4GL)Fd+C\$F>#==#OW$€e7]ŒUW}MaŠITnB[[5dhAK…[c/om.kp=dnDZl>¬ƒA£ÚƒÌž§d­“W€ˆK]g=]j;I].QW+nv7xšDM¤_Yv=a„HJ’d[€Kl‹E`LiLrŸ^u–Pz”Q“}CˈHãèŠäÿËÑÿ¯Ðù ½ø®¸†‘œ`“”]X~;gv-nˆ:\yTmp@ul:gm5in7n†Pyžaž“c’‘]~{Q†w]»“v¦Æ”ºÂ‘û {¼¬Šš¨‹n]•m9_r?OhCq[@•pL’g”{Rh§m•Y­ui–\rf:l [\~U_T>LL6NB/D<+C2'M6&Ob2Fi:>R*/7 ;3:Q)[Z9_TAFVEE8+­MHoÑ«P‚WfrEœ€NnftaOwc[zdOzcP‡RXM;[aL`_KŽj‰¥^l~@Mo5ai;~Q’F‡J|jBjl5cl9hwBQo@Lk;Gj?4I)=4)^xSAŠI;W4J‚MPŠEa”G_zAZc5VR.AP:maLwj´wl˜]Zd;atL“©l‹¸l—¥i®œj®žqƒŒ]¡oO³¢pÓË…ž¼y­¶³Ôñ¸w¯¯p¤‚`°o§®k©[ÄŒR‘o>uzGd‘K_„QŠ |“¼ƒg¢ZKt5^f;bo?n‚Pr]“[‹PŽvCx]5_J+LA+79&74"8B(>R*:X&Qd;N£i_m—Ol‹R­tƒ¾‚³z²pqŸaf„NclHlqZynš±}§ÎŽ›Çƒƒ´oy°re¡i_ak‰b`‹Zh’Xm¢ku§k‚±c…ªYyŸOp†Dd}?\{IXyB]€WmŠWq›ed”cQ`OaS€aiŒsq „­wv§\bŠJpšTm¡]dMOy4F^&>I!Z|Vzž€­Ø¤ÖÿªÅÌi€¯\t£UfŒM\†HF|<3c;2];:];UkA`k8_d/bW/\_6LY38Z/3N'5P'BV)AS(]jEqiRjhMY[4VU7HU7AT8ISH_dUg|`c‹bQ…cVTX€@A_2/*#.&219&A%"< !2.54JBH.YB,`K2^L4JM6]C:^S3RQ@>T=>X5TU,Xh1_sD@aD2F9R7&@\.9=7D@4JI+Qe:Jh7SR.Kc1/^0DF(JFMM"PO6bO:-!;E"-X&2>@AgS!LlAN[:ZV.^_zRKF:Kb-Kl6Bd4:h2AT-NY2Gg@kUAhnQdŒp€jdl‹S_˜cX‘b]sKTz<_€Ma‹NK_O~Bhp1x{EmŽQk_RˆVCgGQ`0Ko5gb2z‹8|²ko¤dzƒ[p®YU¡ihqUkŒWlƒWj”Rd¥Xg‘TRuIRa=OiA~\Ga¬II™qQjSWj-Cˆ;@aD<\-/C'6>!R<%bB#[‚:\v7{Qf¦faƒO^ALZ>ER'ZV"Iz7fK0BQ4h`1Ug.Q[:Uf5`n:fu=Lx>f~B›¥U»Ék€ë qƒls‰S]•XLo;Nb3E^*ZS*ou;|–Ll®WXŸ^{vCpq7bwA\q@fvG¥U–ÚuÆt_™PPxEph=ä±aÏÿž¯¾y™P¢¹dq”Z‚x?yYOƒIZm)gt*iˆ2f|:dƒEWo?ie;€š]v]fvAjV-ŠI2¶I6ðzW½¿–Ñ‘xÈ~c»XAÎR6WbCTU/xO.‘gBrzQƒ‰^y¢iykOŽfÒ|°nSjEUY2€tIpº}`^CU>)JB+BC,DD5F@/Q>*^D"EQ'aZ:}]@„gRNnY˜VAÕШd¸‘^ƒR}‡R•…bunZŽjPƒfN~ZEnT@`C4WL7eM>‘SAqeQkvJvSsaOitUzuD~N’›Vƒ~HˆV3»…P§Ær™ÍzÀu…ʃ†¾a±qœ•Av”\\sD_e9ilDq‚O¨Ÿ`—¹ƒŠµ‡pžmHf1Ud-Vh9qs?t‚Oo~Ebw?Oq@Gb6Re5Yp6TwBUwJCqKOq…¼lÉŒ&AH+E]8Cc0Gk9\|Rg—`nªv¢Ä™Ê曻܄ ¼hŒ®^oœPZ‰P\‹`a˜b[žl[¡e_“TiKrl?PS+NU+U_6ppCgkBJd7Gi:Gg;D[2Ld6W|I”Y~˜Zg„V`uV]fNppX€z[p‚WyŽIZ8MmRw6Ki8A\<>\AM[=Lb9Ie9Nj3P^9ZXWyqlWzgBo^UdUefHUnO^qUcbvŽdrŸ]hW|wLki:%%*;(8 /5'?##:#27"MC'a.1C6:=(7?'>@&OB(‚F*8S4@>4>F'DQ&[T,Nl22gA/::2,"c2!E_3DO;DG6IB2]M?Nd=OT:9W.2Q+BFBOeIYS*O`?0U;:L2IT)Lf:8kH>D3AB&7;0.2,:0 /C/J 8:sHGo>DZFRN(UP,Eb0G\/M^(>S(PO&Ri2Kf1Pd-^]-Rg2Pj;EpAGO?BM+=[,>O3BP+Bp6Nf3=a5eD0s`0UuQXegna=l„SQƒgUmHfq4j†?^‘SW…RVKVB\wA]q>\v9HxCBg9F^3FU+_a.„Œ9x jg™af`vvPm˜T_¢b_„WX‰WpƒIa¦TH„U@fNIZ3Dh:WZHŠk.UÂeA‚j`hJP~&BxL9_:.I(5B&6W*NN/Ap<7cPFX5Ot2jr8Z•K`ŠYSˆTZzIR…Pm–UU¬kA“€Fv[YxQVœXF‚]@eKBa:Vk4_^>¼G<¶Œ>|¦zwmWsPOI5QE"\> EP(\T-^qEL†_^{[E}5EZACH6hd0jE_ŒIVwKVcnŒKax?ruT»z˜Ö¼Ñ}‘¢j~yKRh8M]-Ta6ig6ppD^tNXvFT{JMp?Nn=Jj9YkAg~Ph•n²™«âÑÕ©@‹P>L$_e=Lb6>`5C^4poA‹ˆb¼¹™€³‚†“d¤»vY¢VGqDJ_8‹d=Lq~Ct}L‘{Oˆc ¤tŸ±m–š[ªcز˜ãç¬ÿςήaz‹Jnu>n€FY}DVb?i‚Plœ\j™b]|RstUnŒZ\‹Ze…Y`‘W]‹]i•hk“bvan”P`}FhfE„dR`hEI[9GN8OcQ]‘[}œa b‚¢g’³qƒ©ed“Oe‡]™¦•¾‰”Á‘©Þ´šè·šàª„ÐŒS°eM„SsˆX i‚µt®ln•]z‹jq™tp²{Œ·—É‚·tlŸ_P~JO{PXŒ]i›i›hXŠQ^nF]o4Hj-ES.X[3ZZ/dU6|gHy€V…‹X›Zv¤RP9W}8_„;St0E].Fb&3V-0T0@T;[i;Uw?aZy°q²wŒ³¿Ú‘±Ïu‹£O~’HoyAXq?bvNg†Rj‹`o”_mŠRdm>b_4\S)KL-JZ3Yc8jd$+U++K:2;*-:<:D9EB)4S7;;46?)EJ'ZQ-Ik2.k>?G;AG4\=*G_39cHLC@NH/QF8_P=C*3R#6=$4B!]L"KQ%BW3H]0Mh>aa;TU65O>@=)@@1A',0&*,5*+<2=^DOv9HhKES7BQ.JS3Fa4;=2AE#Hf3L|GKmFJoEJl?@q;Q]6MV4J\EMaHm_HtJCv\LaLS[.Zp/Xt8XwDZ~HUNUCH}OInEQl4Ff78[43T4eD)h:\ŒgmfAVŽDWrZpuTq—]džV`š[o¨Wh eN›eAySMlEGnFIqQzrGh›PQ–mQ…ahuAKŠ6BhB4_/;a3KnAYvBVPP‚[^ƒLZ™VeŠPs˜Sp²hn¯vpªu|­u•»t˜Æ~ŠÕ‡À‹³}¶x|²u^°zS—b„;T¦^yi¦—a|µgYžn>kR6?04O+/=#/8E-e6"td5h¡kl‹O_jKU]JloCf‰@eyLZtWed>`qFo‚X˜’eu¢u˜‹C‚~@Ub:g^.…x:\zEEcCKZ%\l8SƒM„mIhn@LiHSZ+[hAnOŠž[œªeš²hˆ²‰‚°iª‰[^ÃijXvjA^CiˆNh‚NfhBej7m‚D`t:g]izKŸ•Lª^w˜P•£Q¿É~ØÿÁÐÿ¯šÜ€hŠZgV0bEVk:McDgQ:q—X[—^U|1X|+}w7‚—n‡¯|vª}i[C\U1OY,RW-jV:paM˜|Wɨ}¦‘sa`Ffd@~[Œ‹eª…^€y[‡aIƒWH£jQv`YH8…uT–jyžbZ•YNL2VC2¨_K[ÍŸBNE¯‘I³½e¶ØŒÏáÉ䥸ô¹Œñ³d¿„}–Jw—Qˆ˜Nɶk´é–žÌo‹Sg]‹W˰‰âÚ¥¸á¥±â¤›æ~†Ômuºcs¨q}¶‚yµvi•fe™„ŽÁ–Ë}’¶|œ®wš²‡Ã€v²kj¢ip–jv›irXi~I\x>UpCMk9CX-AM%=D!38<<(HQ8PqDY‡OWETu6Hj/Ux9Q„4>s/>e=PdM‹W;aCVdBTuGeŠ\ˆªt’©l„£n·¢¹euŠ?_v8G`+FR)D[(KW.PV2Wh>_wC^o@Xc5H[-BI,WU4L]/LW-Y]/mc?jo>Qb2DY+Ff6Vy@\Ms…e‚‘q}¤‰·€’ÁsŒ¯rˆ¨l€¦`WSUyOxV|J`u6BR)2@2DO@acETnMfv[j}M5U.6&$*@;/cJD…Q\WPb\L^dLdf=le=W`>_l@]pH07%+! !*%34"8*5D45E'%K27)6.E3]:"L<.0D//6(,2%@; QP"Rg0Ae9=^?9K6HM5CL3L=)9N)8@'9@!;F&?F dD$NW)>T@AD60I),F/7C!.G"-;$.A*,;+#6+..$6I%rS&L{:LeRFoFKb=I`;HX4KN&BJ*D[3Hg;BdUtCd”QXžh\ai›Wi§gk ie‘VuZŽ [‹¥c‰’QyI~iA€q<Ž…C‹‹SqwTqgDxwBqoAefCRtCpz;p|8r€Jw‚A}ŽKe–^V‹YIH=sH=V1.W329-F2}D%l„8tŠMv‹PZz`_wDVn7g^9W[5t[4‡u@„¡^¨ªjv¸xi•`Rp3FM1T[0ms;]DKbDU~;i”Mh–QdŽZŠyFQCTnLqjCz¬`nsNij8ÈL4¸Ÿ^”Ṛ±t•³sr±ŠoUiw@Šr2gtDXwBwŽNaTWq?^W3Hc8KW1JZ;vk+u«\‚ _a…<{k2’²UÍá€çÿ´±ò˜Š±`Ve@_S7k„NsZŒ­ie‘kƒˆS\£oYAl‰7ƒ‚D¢l¶yneAK2RC&ZP3mY=€e†pp´o}[lrQŽ]¦‚œ©£€W‘gSš€gŽ„i}iL‰XcqZ…šlc~a‚…_wŸyK„UYF<ƒTD©¾‡b›y^QB[UDgO:XQ9AK4UI2Me6Ga1T[=?Z9:B/MJ0|]1Z^.__7 ™am–`m‰Oƒ^¨´€£Ê–ŒÁ}‡£nª¡_è©n²¼†©»~¹Ë °Ý©„Â}†£d› p|‚Q|Yx•Ty~Pž–aÈr‰µkv¯]€£M§Ão´ß…¦¢^³~LÄ¡jÈÓŸ™Ü¥kž^t>€‚X•«Z³¾r“Ñzp•RcvZNuGOj;Wy@[}9Rz4V‹Ip^k¢hi—iZ“Z\wCpƒQr€JnvW“w¨°…¼¬}u­z4k6Lk>RzLpuHƒ¤l_¤j¶—wÿͪÿﳪՎ—­kq‹QTuEd€Tr„X`MirL„x[—Šc£–e™£k‡¨oƒ“X§ˆ^â Ñ¤|Ÿ’cˆ™[˜’\—“TzˆO|’a~‰V„Sr‰OqzI^lAJP9~pUެw¼w€¼„Â’€Ä”Š·~z½„x§pp›dx˜c}†Q‰U’dµ­¾¾”£À†~›_npCW`5Uc>ZwN]zSiŽY]ŽNAi5@f5u†Z¬º¸Ú޽䔫Üq—ÇYŽ¿f…½zˆÀ„ˆÀ“~Ìœ“ئ¦Ò”¯bt~Gn{R–”v¸½”—¾}} ow owšcrŠL\v8Yg4Yg9Vi9Re0BV-7H(.?&.C(?S2\`?x‡PqHRv2<\$C\,Zs7Rz6Jx?^ˆ[bp|GXsP]\cžiаr²q|©c„ aŠŒK^b1OM)=L 6@"9E9"64$22#*8$*1%9>=BQR#RY.CY=%9C%LB _O*>V6GY9AX6/Y;I]7Fk7;\5=L6>P7=a;D^=YjQ/NN(RZ8L{MVrN\wLKtNEq[KmV1iM5HMO8&bh.hŠ^j‰s_t\|n_zRRŠQOˆOYyC`n;gdElT6GlH8`X;YDLS&Pm0Yy>_‚H]‘V^‰nQuMNx?CyF:a9?L&Db*Xj.f€8L–eQxYiƒH\‰>MxKguL`”UqSy£YgžY~R`œ`?ŒdDbGZ]0ey@hŽUQ˜cFxSVv@^‡Ih•F{«^u±rp©lzœnwŸ_q“d^…Xh|Mn‡UhŒPIgM?U*<@$7BH:Te,bo8`zQVoASvB\nAV€HRXWyDKn9Kb-DL+^K4Yz[Xj\et4Z†EWˆFU‚JA\E@THSL-fh.}v?Š‚Cy„PY’[Du@M_;PX=twD™RŸ•Z¤„O¥~M^oLft3E[6G[/…e.q@gˆHnNh“\rŽQ^€ShiR‘k@m—TT]²a:iTJA,Za4ñ='±w9ƒ½‡¡šy™È‚n±pYzJh}GSn@lh;‰yDi‘[Z‰DVv?Qn8Zn;MnFsŠI®{2q«^Mq:lL$™j-ѵY¿ó“n‰[\^1\b*n;ˆU‡Ÿb̪jÆ…‚žb_Ÿ`_wFh†F€“U””W€‘\XpG9N5dB-pd>ƒmHÌzO¡’oŒ—q€fŠ”n¢u³¤|Õ´§ˆm’€dŒ~i¶iQ˜|ZroMÁoM‹nŽˆe„kT”yZ‘~[ƒ«~bv[~G?¹|^½†’\MvaMfO>Y4llBnwGetH\l6okCJgE::5>C2TT2G=&fK:‹‘dl®in‡Y…n¬ºƒ©Ð›–Î’ˆ½‹~¸o•¡^»»k°ÁkíXó‹O´ŠTžžd­ºœ­o­c‡©b‘Ã{¨Ýšœæ—’·m}¼m»|«Ý“¸ß‡j™^EB4dgJ–t[ª¦}kÀrwB…„K…“_”ºd›¯bywC†gVe”UZ=m?g¥KgŸJu¡R³r‘ÌÅv¶tR…L^O-RC/`XT­‘´•¨{‚©z9}ET^0mŠL‹¤e‹ä„„Ý‚{žeœ±|é¶Ž©Ç–††VdBSiCrmK‰xKƒ‚Ub}Mqg@ƒdEˆbG¡‹W›šiˆšdš‡iÔw©…`~rQxˆNuP~k9tEmNlOnxFm}HdtImdEVhEi[J”›gŸÀs”¶i¥À‡¤Å’‘˚‹¸¨|µ‚œ¾ˆ›Ÿx¸»†©Ã·¸yÀ¡r¦_puD\X4WaA^€Wbhh•fihPYU…\m©o•ҸݱÕ˜µ]z¨Lƒ©S€¨_Œ¦tŸÈš©â«¬Ý—¡§is‰IQnB^sIv…_”šsŽ«x~ŸoxžswTWf3MW*OU2MS*E@&IC-FQ5I]D5=)4*36!D[0Eg2G`GaƒZbŒHXi;TnXtc…–`›\¢_š¡WgF\b.@C+;A 5;,/.62>%EK3N_@Ei?Bd0N\:irI]{IInR):C$JJ,Vg5[?eˆMŠ‘b­®k¡¸a‹¢Ok8Sl8apM”‰Swx;X]2FT3GUK1AW8=lc.wXq‚y–†fŽtg’r\‡f_ŽdRXI‚RSn;R^4UfH?nW8e[JX4Tg1Uw@owDj¢ZU—pJ€WPs>Dx>-^<:9,GQ(Wl5j}AY‘OP…b[}QXˆOW€9b‚AS€\k[v˜Vb£gj•[v‡NP£mDz[O_A]m>j}Sd—Y\®in›ms¢k‚­lx˜ZopQhFYr[[c@NsFJb@mwGp˜]KŠY2K@8.7_,Ea<@e;Kh3iu7Qœ_X~XSƒLd‰Kb‚LQ{GSi=E4@]7JM-iO._xWEplHR>OG$][,ck8lx?KuEL_5g[3`‡GuiCxf5etbVWnJhnžQD˜¦|€„iŽƒdjS`n;qiB{e=mwMVtU‡yK^†TOF2PP6?P,;B(bV=sOr£]m“VŒ˜nž·†­À®Ô¦­Þ¬Äsq?Œ›V|§dg‰N|_™gŸ¥fËÕ‹¼Æ{§™Fy6­ŠL½£_»ÂzŸÓ‹¬çšÃÿ¼Øÿ¿¦ÿ qÅzT¢hެˆŒÂš¤j”XV{N…yF޵]ˆ­e}¤UpE{cD†Ck?c“>{¬ZwÉnr³i©¼v³áž£Ù»rRwD.9-) ZB9ž–s¡®r’“e}‡RUvDOh7tžPj›W®´f£Ñtq¨\šj¨¤æ·™lŽ_Yp>esFryRnzGroKpoG_]Eof2$0:L(?h6FnO`„bo‡JLn>Vsbo‘ac{Cek;]V5rS8q`7GW+;H&38 .5!-6'-C'0F.RjPe|SW|?P`3kfKq…Xc…HTl?If;Gf:Go>Gn;VfY8CbDPs:]~9fz8g‹GrGj‡>Q~=Kq>FyHNh9\W-EE&>O4E]GZuI]vRbpGIa;;U3AQ6?B0,8%*,$E7.;8#3@*8K)5C*1:->H4GZ=Ua:Oe:@`BRp`t‰l) !%$ $ $)"*,+%3"6!&0"#.&)8%B9"1M+#?+&2^)WO$6%>E/E=*\T,jO7Kg;[iA^>OU.fa/PyB>TNDX3)F/8/ OGNW)PY8VX8Pb7:S3AB*aJ$AZ'NG/hE&pm9pX\™tU”jNx\9pZJU[nE0{y:v’r•„›‚{ut¡j]šrS“c\ŠYV_WY]†PNd?‰pN‚Rb}U_xJs|LxMh•bUšbV‰QM‡I7vH>Q9Od4]€Oj•__—ZXŒUP|KY|HW‰F^|@c}So‡X‰•Tk±hp›qx™koqJ“sFeKQssƒSP}WB^E;J/JY4BE1QG$Y^&Xs4tu5c€JLs=Ic.dY.V8a{=lƒAIa;9L1LH%RD&mL+eT.^rDJz>Fb/qj+qˆA†|CzvBtyA]CXt9zˆKz¤^j‚Jnpiu9µGê·vÈÔ~mÈ‘l™h‹”V}—eWoGfV7~o>p’NQqJah=ŒX/©P­™hm©fG}H:W$[vHË‹Êÿ£ÄyrfARdChmAziFƒYƒL”ˆYˆ^‚†\sœ]t“SŠ¢l‚¬ng‹RroD‰`A†nV‹bGŽV=‚R<¼]B­vUt² b|lzx]ªwPÈXÿ¦xËầ—€ÿ˜wÞ½ŒŽWw[‡£y¦©v~‹]UpgJqX@†Vr]_XJ}cN™¤w™¥zŸšlq–_„>®\r‚\z€[~·w|¯uR[x:T`39U2Ig9awDa~Lt„Gl”_ƒ£g¤¸Š¸Ë¦éì¼Éø«zËwLt7|o;…ŸSv†H‰‚L¢\•TÔ¢i™£\y¢QhŸVx¥g™¶}¹ÚÆø™Üê“äÒ}×Ù{ÅÀx®¢c‰S ©e¥[ƒ¥Jms@qoHh˜Z‰©U–«N—G|=…ƒ=c„7e6d›YY9WkMm€a“…u¢’p–~N¡‹O­‹UxƒMv€Mu”XXŠOd€H„}Rv‰d}„[‰uOztY§z‰Ë…{Æw…Êz‰É’ךšÔ’¬ö´­ÿÄ ó©¤Ü£ª×Ÿ¿Õ–¥¼|©bvHkVBxLhŽQ`zD]xHd‡^n¢s~¶„—¿Š­×žªâ¡­Û—žÉ¤»mœ«Y•Ee’;UˆB_žW{µj‡Âm‘¸j‰Ÿ_s|FXi4[cJtŒfo—rv™k`ŒUVnL~„\}Ž\fu?BQ)AB1Y]JehC_TQ,0K&,;4J#.P!%K#3R%>`:MvZjXbˆAcqDcxZu‹elKUsBHf8CO3UO6_f;XsABa5.C#2>.7C17N8I`J_{Vk€Res>Qg5XcA{uRo„IUv=ZxAUzIX€LOsOJtJJuSU~^TŠ^X‚MT|]ˆK_™RV•KR†PZ\XŒFCh/1H#/D&@Q9[hG\yGHkG+:E+;G&A@-AI7CN4B]5H`>Rd@GgNj}\"!#!$ #*&,(3&6$ 5!"+!#*'-7,Q> 5M(#A+1/[)=F' L9-(1?6"QH*=]2KI1Z]2@n9=M@)F.86,9C'0>&-:&;%2 &-+,D,G8KH$WU,J^:EG<9B&LE%kd+>‹IRVD;[3.@39?$YM$Nb-E_6>N8KH29I'=D&=P!=O#8A%P?#gC*ka;qr_smc¡sP‘^4rYVEDxb+y˜\s¢np—ng‰ij€]j]w–ip§hj¡lo›f…§`‚»ix¼rg´kažrUyTkOz‘Yj—]ebfSb–PbœMa™Sq™M|´hz¿t_ªt`‹\VƒFX‚B[ƒCWŒF[ƒEfH„‰NsžVc`l™rh˜oCfSnQcx?R‹[fnIf…G_POvCKG7Hc+=b0ZR-OwC>nM9SB^T/]xBXy?.kG5C/FX,fq=i›MCždNfAls8n‡=^’`[sGfzFr‚LfpGQsbGZ]4[„C]•\M^Pe=Rh5:^ODK0AJ,PW._W)Vx1Sy?Kk=ag8mwLV4EU0SO,Qi6Ye6˜|E Ãi©¬jˆŸ^{¬t•¦cgŸ`W`oX1|yBp‡OdfDTc=`R4Z3Œ?ž¤mKŽZ_b1¹¸Sèÿ¸³ðœwšgd€XpcCuoA~iG‹h;oŠH†F}’Kc…Ge_2|€A‘ jhšccW2uU4ƒlB†kKzfKfbS‚fJmZ±nXâ}[ŽÊ¡¤žŠ„›}rkVÄlGå„Q¹kÜ‹lÊ’o„‰o„|U¨˜o~šqzcNvqN{–c{W…„UuyTflMbC“Š^‘žm»›r³h†«\ª¯Rh‡Í‡‘Óx؉d€RSf2Jk:KZ;ozKe„S\zLf|L{š^½¦Ì™ÕÜ©ðò¬¿èšzÀzM“OV{=|J`G^Z+]P+l[8—w@ly8tp:ˆz@š¨_©Ô…»Ñ‡®Þˆ¥×†qÃtttEƒzB—d?ƒrL|K{‡[u„^oŒUh~N‹“\~´cu—Ftv1h€6c„5Sl,\h6b‚b`FsrPekG\[DhkS\pJTaBTgGvyOnƒF?]8_PL€[O†Q]†KhHYo>I^4EW8UfEjrGXtBQtEg|La‡]d’_`‹R]|KmmPojDjd8TT4UX>Vg=OgEtƒUx¦\džPgXrSUi65Q&/D.J!;K5O\:Ud9BY+;M2G^<]kCkj=ph:oj;fg6TZ3QV0;L)7D+FE/QU5ES3IW7@_AGhFKmJ$&$-*") (#$,%9")>/%7- 0(#-!&/(3 <6 ?9!@E%->'1/X2LL,-S<:@53D&=G'=L2TN0QZ8Kn=Ja>7T?H<08;'(8(2-.3)9"$/($-"G2SP'FY4(=665$>> P?!i[*Kw5GQ@BJ9CP2HU0N[0?N6K<-=h:BOFDM-=A'6J(;L*/O168,G=-^<(_a;_uYbp`ueE„LIXNtY4†ItgY‹^ZƒVm‘Zr«ho¬vlŠi^Ž\lqPy~Go‹Uu‚P\QH€TTqMj‚IwYd chSfš]dZq‡Nk—S†‡H{²^w“h\™_R~ZOxNUzCV{=V‚;T„D_Te–hk’^lai©x_’n[Š^a‡Fd…JKRTlN[o8R{A9Y966&OC$Hk2HV(Yc-Rg?EaFYc;GeFUe;=|LE[7OY4_\8’D^ºlV‰\SjGpw2rZw”jhwMJW;EK(dT)nk1j¹kR\?WwAg„Ib}>sk8†D™¯_c˜e‹…K~•\}yRz~E_iHXqBqm.aq&YM.kX1X\DNK0I. wDk±hSlQÈn+Çáu|—všoI~°‚i”r[@ch@]\:bn6h‰DiH_ˆJZ‡Ruy]}™eYzR^R7cE*‚S4„†i„Žl}}O²‘y³š}{eŸWÿ€f»Ÿ‚®’~w|f‚M:{]G¢kI½¾€Ò“yˆc‡œv·Ž~–~…fš{[Žz^|]‡™ax}bmiLxgTŠyN–—eÆÓƒ©Ðu™Áo¡Í{™Ì{¢ã¡Ýš‰È‚[rKK[9Xl9WPuUeƒO_}Ig†T}Ÿi›²p®´†ßÐÕÙºíšá¤l·la¥Xo˜PcŠSR:ro5‹ŽN‰Nl€AguEjfAªžfÃ뛼òª¼ùŸ¯ì±äƒê†‰Þ~cÖx‰’\t—Y´™n¦}ŠŒgp„U„—Zš¦oi®bRKTs4Y]'Q^0TE\ŽPa”GIq93?":-Q1!hh;dŒPk‹Hxu:††J^wETgBgsLh’J\“B_…9Lx1Ib/s~N›¼€\ÐvV‰NTG[Kdu;hd2`m=]o5aq6gk:jrN‹ˆušÇ®€Ó¡–v¬’c¨Œc»~˜”z‚Žhm`pmP–¤qšÈw‡‹Y‰‚\ £uš–n¢‘pÛ›|½©x˜…\°›Àí¦°ç‹»ÝÓñ Õý§Ôþ¤Êü¯ßÿ±Ù÷¨´ÖŽ™Ë‚™Áƒ{§ofvR³s]sŒVftE’TtGd~L~—nš¾‘´Ñ°Ñ†È…ª¿†¡Ã}{«[`z7>R%9G1bvDg“Lp˜Gu£PoªWm¨NY‚BQh-Oc?RrV^Xu‚PkPnƒaq†[Vr;Kb/W_2QV5^F;r^Iˆ_IbZ?AQ>PK6smL{†TXwHEi@H`7?`5BY2D[58U48H.?H,F='MG'99!093UYDflA@S=hjEnxGYkLizUW„I6g85S+/M,6W23[8@U1@T/6P28Z=F`@Ga;KbGaTBK9IE'JH&S@'QR5>e58I2LC1[A-^pFOy_SsZPpDS€Ias?\|HUMTmCizM~’_wva¢zeƒgRˆUUsJPoHOqX_XKStKPsGZ~TkŒXp›Y^œclmN\{JS€S]}P]ƒOzNn¢Qbk`™aQŽdRmERuAQ}J]€Gt‰Im›`n•soSp‹X_‘\UxUJiBeX6f{4OKKoVXm1@j=,B(:)MH!Bj6@b3[h/WwJR_?Zs;NfMgn:FO:RE?I,aj;‰•MrÍ}JŠgHZ?{x7ƒ­PRyGSE9S)=\.LM'ªM%“ƒ=?ÇHkT”p(ÖÏr™ÿìF¸ÌGOAVD)\J5m`?f_5aV>YR3p{D]‹Sms:[u3}m@wM„V’Ww—[VšmZOZv5Uh*Gr/A\.Ri.Mn2U\/KM*[W.f‡FexKŠtAS¤TYfBZuFUoMp’H€¤S|\i†VYtGƒpGv©_Y€WqIks…n@ÙrC„¿{i˜…b^BLg;Sc7b]/bz=rB‹“M†¤bzš_i£}X‘sVicxZM£gO†‚`w~aÕzTÒ£^¬¹€žšjŒpÀ…m–eZ‘]S}dS‘UD‹gHܤ`Žå•”jWÌ’lëÛ¤Äòº¡´”˜|S£•lz|f˜–l‡¸‡…gŠ’_w™b¯¨q¹å—Áv¼Ás³Ü‡­ìœ®ç˜˜Ì|…®kKkAN_EN~Kˆ‰MzŽUf‹Od„T{“g‡¢s¥rž¦qɡ¾æžÉ멣㢈Èqz¹V…Ãj—Øwwärp²VŠžV‰ša°b»^zº`»Çâÿ±ÝÿÎËÿÈÁÿ¦ºð ·ï²Ñs²ÃhyÒ}‚±t£¿~¸È‹À…x¯my‘_މ^¶ws»kS†I3O";?^@"sd4fw8O_03<),/+V?+xyJa‘MG8`rIo3Fv:qF¾µuàÕzs»be‰DX~@Rj7Hg7N_6Jg9Lf8WrBlxV{zgº‹iÑ‘r¥„ZwH}wH¡tP•}b§|[–…\‚}[¨‘s¶Ð—Œ¼vrV¤e¿©~ȤǬxº¡p“€V‡gP½˜o¯å“°æœ¼ñœ¾÷Á쇴㒼존ñ©¦ë¢“Õ›‘¾ˆ™±yxƒ[‡jGu'>9'AC*S`9cfBmjVeuUmp]ƒ^T}QYpMt€MbKTxKHpFBd9@^0=^9Jf=Hi@MfBKnPYtQZn8KT3VfF^uLWlA\hFbhFueI•zLyvEyxJvzOb‡b†¥€´|x \hvFSb2JY-EO4YUA]_LaaF[^@P`5E]3ThCi~Kg^šyˆ«q`Ž]Ol:4O.4=(58#),(EHAkoO^uI5[CM]FNeJJ_G`iEXjCMgBF`MFv[NƒRAq<7Y2@Q;R^DOcLP\F`fMaiBR]U5@Y;B_IZndof-$!-&!1 -+=<=S0&IC(>4"?3!6.%. &5"$6)-<,'=(+2$-738!0>%L:)AF0.98D.-.<%77$8<)L@!?Z//G4,8+<4'1:!48%-/9-AF& B*R6"J[.=s5XV<\d?^v`ay[YwJQsJPu>Rd8Jg7Yf5 KE!E`5Jkq=pd>Qj?J‚4Ki)Ni)Fy2Un6Rk,NZ3RN2jk=`qIa{O}‚M_†Pa‡Kdy?f{AzC{‹OnoFnrEa†Q…vAgŽXV„QMqERY.f^5\s@ºY4®µŠLštOl*fi)ŒI‹o•’s‡“e·‹]ȳj²ò®©ñ›\»uz`7mqA‚K§’fƒŠZh²dzoH~KQo3^}9w¢N}Ìat¶diET,–tD’˜l}¶„y·‚w¨Šh•om‘l£rŽŽ_`Ÿ†\™huiaŠ|m„pdwlUlJŽS¢eu‡e—•{ì–hÿ£k°¾®šrÏ´‚’¶x´«c¦Ä|•ÎŒ“Ñ‹ˆ­w¢šh“«b›Y’®w§Û–°ó­ã‘¡jo…NLuEWUEYlJv”T lnžav£n‰²‡žÀ‹–³w¬¾†Ñë¯Çü¹Ðù­©ÝŽ~¶eI­ÛoÑÿÀÿ›žñy”ÓkžËf”Ñe±a†±g±Ì~Úó¬üÿ»íÿÈÖÿ±Èÿ¢±úŽ‚Ê}‚Š[¤°~¤ÅªÒ«Ç¹±„’­vj‰VsˆU£´w•σU‹M0J+6L)/D!0:98$3Q2*M,*G";@,LH5`U6YN/OO&Ti0bf=pƒSc˜]f‘\k™XY‚HG]/KY4e‰d“Æ‘—Á}pŠEUh3\m6Nn6Ng5Sa9Fg8NeIfŽjv‘Z­†R¤†OrBpoH\U\‡ed„c†^~€Q‡Ž\ž’c“€É¹¦¯â¢u£cžiÊ«ܬƒÌ¨o´–n™ŸsskMz^O«…j³à޼ö‘¯Þ}®Ûw¨ß~¦Ûˆ¯ëœ»ò¼¹õ¼‘Ö‹˜¤p–lm‚Nj‚?b@Z–>Vz5Ta5}u\¡}¯¸z˜·y…ŸRkx8opG‚›\SŠLLn>Ij@Qg7Wn6Y…5k˜Cƒ¯Z˜ÇyŠÓzjŸag€WhŠT_h5KQ(3>&+4%5"*>/:J:FPMNoZQ}On€Vz^†›k¥v¡¬suŠWlyKppPdwMf†UVNCq>If@IdV,>[4P^:K^6FR9Y]BOeG[b\$',$*2!9.%??&3K05L8-J;"B65..7&0@)-E./B78/$+ /1C?<7%V3&4@*2)1;("9<%8=$85"J9 3d23E5,;(99!7B"/=!*28*7=$E:#FR-BI70;+67$E@ =Z&X17/+K>D[/;g;?Z4R_,ti-l„9`~JwRL[W9Gd@9G;9A.;>&0J.,-&,45B"JA#[G'ay:\‹S^„[SrJCa>DF3L\-Dr?MX6t_1{n7…Sr™pK’u?g[ZR=lv2fL`‰S[ƒY^ƒNc„W]\Q„cgsKVL`aBXv@^œQe¢ha¤k\wq–dx¥fe¥sR‹i_vUHlLLe@O^1Sb,Ml[O*k5U^DjAIT,RC(=L)AX4PZ4XzHXzN\}Ie‡ZL‰^\|Zm˜]l¤gZ¥dd’ZqS¥ª[{Ú~Rª~qvEZ…ElX4d}:E„gFi?~›\g¨rb‹]X•PQAZ}Cf‚K_}G[xC}…F[•aqvIm…I_UHk;QO3fd>ak@ÇP½²lO…YIp*aq-–v>Å™dܬ‚±º²p±uPÛÆk´êžW‘[itCpi6]6qgDŠrV±mH‡Ë…\veFe’L–‘M–Ùk~ÜrHždEO5rT-Ÿ[:´_8£¢o—¹Š»’„¿—|¾›…¤‰šƒŠ—m”‹_Šj\ª~p†t‚k\dKl‰Bi’Y’št—¬†Â {±¯ƒ¼™hÂ}N¯§p”e•[ŽxUž›q¨·|‚φ‡²n„¨e£Ír«ä˜´ï§»ÿ¦œß—zlje’\e˜XX€Q]†ZuSª©q‰º‰ŽÀŒžÄ˜¼Ê™¥ÏÈàš÷ùÆÝ÷»Àî—ÐzfšVjc1§¥VÏÿÍÿªµÿ–¦ö‹Úr“ V|—YšËyÃì—áÿºõÿ½ÞÿÊåÿ¶Îÿ¤Èÿ£—í›~¼¼ì½ÿ±¿ÿª”Îu¡¨fŠÒyhš^v“c£¹ƒ§Õ_WHX7A^14P"(@%=^AX‡WG’V:ƒDOh:XdIZƒ]@qTBQFau\X•krl…¸“qËr¡n]’a;lFIkKˆ­t±Õ—~±pJb@CY8NZ1`k?IjFGrGJsMjwU¦ƒg“‰ekkFi]EXaRmwm¥„¢ª…£¸œÒ§‚Ή~³ƒƒ±tœ«}õ¹žëð®”׃|³e´­n̰|Ò£l±¦k¾œd‹[j_KT_>€W=–oG”B“ˆN¤µ\ŸÒr°Ì€°Û·á“›Åx–Z›“X™…Dh,,""$$)*%%)/"3-6B;17+0.8'1/7+-#"-)*3+.#&- &!+"-,&:,/ '"%BA-U-D%)$!!,.+&5"%# #/1 >D->>'E; D. !  "<58|PgQ3-+ #%(5.974N/GC(TP.'54+    +   % )   ""#!")")$0 +<4>EPZ^I`cBQQ:5902-3A=-84/"3.2.;A/-E52>3/=).;".203#=5&>373>67;*RG6e[<[\'23#++)#&111BKALR8?C%ED#LH+FD:FB4RA0NB+x[4–f1_R%:<0DA>OB5I8)I>=;?>1929DO:Py8Ge9BD9KC;P@.7:827VA.CI-Lc:\vIb„LfŠPh„“fˆÈofSVQDLjJgn:I\1^R.WQ+A?3AF1BG>MXQXbTYm[ms_biJYR6MT3NJ;(4;-G1GR7QfDCkK6R@/GC*8o7`¼T¯­n›||wweTly_z~c’tĪ¢¸Àõ¥ÐÿxÉÿyÝÿÐðÂq‘lK_SI``QjeLn`]xSbsFXuQo™ÏÆ ¬Á›¶–´šž“hš”xµ¹³ßóÎÿë§žo‰£p…©jzpX\JEHF4DSGK^MIC?G;234+56&    + +  +    +       +   +     +  &% +    +       #' ,6"?&A/%40'&)+)#!#      & !)#   +   + + +      +    + +         &" $%)$&-"+(#' $ %!  +  +  +   23:J/C949<'A'     +  +    &&#&$#4/#,7  +    7+.5%#-( (&$! %'"&15287/=;;?,9A89>4PV2EWD^#BO(@D-BV!/H7D+4 1'5*'(&2+55#,9"8H0$?!+6*9&.*6*.!(13#E !>(974/A2@@?+5(<#-:!(7"%0 &$"(2#40"0/C(&$/%%/&!   + "&")%*!,(1(8!1!'A!(D#,(0/SlB-+-1)*7(04.)-*4%1:)GO.YO+[K1KO1YY6mjP^T>@9#/*#--)(0--4,G44N2AQ2:N?Yp7IZLCgh[‚cV};IL57>INFAB3;;/03*5:>D/CCMe7OR:8F>BN;VaJ}pGˆ{Vj„_m˜WdjBfi?\p1>B0.6;7O7GZ;DI=:D.5=02DDBM>CP>@3:A0 +   + +  +   +   +    +    +   +   +   + + +               +  !&'"!&"/8#F(F4!28,)-*+!( "  %$$ ##    + + + + +   +         + +    +  +  #% $"           +   + + # +! +  <'B:68+=*,)&*/)4&" ! # # +   ! 8&H<@?'8%)      +  (3=83I&'4    ! "&/'0*! #!#!,%<*@&=$:9$GO):RD,IU7(7&-*%<8&A>?IIKFPDDVB4G6:1!7/+,$ ()4<N%9M*:2&.2.78:)+&$#)* 2; 5K(D'* '"(,"&/B3!   +   !!%'$/$+##) %,/.T,>IWV*FF$F@56+8( ()&BP(XG(O)7^b; Y3 G) S& L5 FO:S+[>( -*B@BE?G0/+*2/;:Cc#><]>I9KL;ZfISf-?;+9:#8B*@I-nG&CA ./&/0"11+44/2D>L^=nm4ej4M\IH`JNkJ9D,*8$%.(,!02+4>7/86.5)!(2&,>(0>38H^cKVp__…jN]r]_ŒbX…RQC[t=Rn'\Z/BC=9R:^e1XgBQdEQb^fz’𥹴Ñåÿÿÿÿÿÿÿÿÿÿÿçÿü÷üÒÿ°£¾~Ž|†‡l^q`PcSJWEHW=DP=EMBDR=?F42>3394/=7.72*;7*72     +  +                   +  + +    + +  +         ,  +    &$ " !*"/%=&I-!M5*7>0#+0' # %""$4" 5)$) !    +   +       +     + +   +  +        +#' !  "  "    + 9,36,48)-''#%"*(#+ + ' 3195B.;P9%<,$)" +   " + :( A=6R+);9"/))('     #'')359B=,3-.++."8((4/"32$48?;&796,1273,NC1FL5672>50,.43$/@,553PF6Mk18Q,:F)9Q)4BD:$33"&%$&/$2.1)%2,#*.(;+$18 188(2%-$,A(474<&7@/86&-+6*(0,)'.&/#03 ,%   +   + + +   +  "!%#! "'**<2*=@2V7$7,%0%0,5F"<%)FFQ4,g'CO n%Tp-'3*"-   .<EV)P[)MP#g[SU5B(2B(-7(/<0<=?5AF}}E†“;v‘=‰¹IUEJ_KBY-DX2JX:HeXOg_am]SqbNswk¨ Æ·–qsŸf€Ô´ÍŒŸ‰…Ÿ‹ ŽYuMfIJpOTnMM}NNoDMiB]fD^k\x¡•ÿÿäÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿèÿÿ°Ýµ‰€ˆmSh[HUPMYJMZ?GS:DQ?CP3?G25?11<6,75)41)/2/02 + + + + + +    + +     +  +  + +   +   +     +    + + + + ! , #  +  +  $3=%D+ I7-9:2((3%  +!&!-#14'9"#*               +     + +  +      +      &+&,%(   +    ,%011657)(4$!  -?&23'&*.#9*(51#*:@'=&  +    +  2 84(A#6.&B$2+$%%!    +!&.0">K&EQ*8FJ? =@I<BI9G=E&+K.4?+=P#3T?K-5K97L+>B-?N!8? ?B4A>*=Y5ENT0AA-6./8)&'* 2*  !'#!!") $747+%%'%*'&0/'."+2' '5*"6'"% !&'  '-% +) "  + + +  + + "!"$( "#+-$,5#:&&% !#  $$D?$@'?#U^XQ=aMTlHT_5OF/nr;_oQh|?ˆ-HN/WC,XC1AI37I6PLA]USHNFZ[9O`B\h6F? ))!-.%"+#"')45,-8(-.!)5"'#!&(*,0241;9086:.05+003,.B/3D9:MH9995>IHi†vekb64<2075/;5B9;@88*3HISV\tLf–NŸShŒ@\]:QXAUdDOdbXfCMyL]uMnyBixGgŒJs¬]–½g¶¿kk›fr“i]Œ…P†o`xFQ7.3=/.1'+-,+1).2, +    + + +   +  +           +        +        + +     +     (9?'I."U6.7>7).." "  ("!!#%'$!',"&&!$         + + +                     $,$        + + +  + +-$+&++(3*,1#$    +% +&F(@(!/>5^F MO+*8&" # +    /((1!&!  +   ($:-&3836B,7S-4W,9M)7R*6N*6M)9Q48@*1<*83)7@1*8-9//5I80O;+G*7B$5E'5B9(C5#2(!!"!&+/R08)*+()($1! !%1$!   +    +   !!*,  + + "+C, + +  !-@::O[IemE:J6EN8K[4Le3RS67?48-TiDPf>Ke8LmCJoPWzXa“Gw“Ql}m­£qµ‡Z~kGlgFl`:^dDeGHiDYjHfu=Vc1Xf+Pf4F],FS1LQ5MX2Ef8@_9;Q@EZN=GM9K;FVTK_‹Op„SyvQszMjrMWpGUhQeIlr6Jc6EY>MdA/+1 " + 633$2.'4,"(-& * 07*22,1%( 7K=/_T?P\3!* +  +  +   +    +,## ! )"      +  %,#6;:#GE&4<*45*)0*(**#$'06.0&"(#)40 H:!=E>F11=,(8*&00.4+.:),4/(&$)3/<*A $# %-2*GQ$*9%*!!/ $"  ""/1)   # . %- +# 7* 2+ $ +      +  + +  + #$  $  &4 ' + 9% A1 (! -P/5M  +   + + +)(1*"),GQIejP\V1/;03F:>E@6J>8M?=FIBTGBT;8WD.N2&;!1.&.-;L6L@9D(1M6:<cšJaw+6O*4*0;)B>0BB5B@1GE-<@A>I5BY_DDXUUpNPb>^g4O^.Ie2^h8ch8Y`8HO9;I96@>0=D-GDBV7ik=LcHWdI=SZFia^mWWcJR`YLcRRlB3R5C[>I`GIgNNXKY^]Ykzk›Àíÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ·èÿèÚÿžÌmppJYI?L=7D?5C;4@8=C77*;<%%4%3*23!$3 &!!"#%" ! #     +    +   +   +       + + +      +      +  +  +  + + +  0*!I(='*3 $""1+-6&-,&--$62#6(-.+(-/1?8K%:'8=N0Ij@hkH>a6 +  +    6 @0 /G/8(*-)/$      !)0,/%:"+%"2.7*-.+.5#%3+, /3&.<,.J5&9>*>,5#/ +$02#A:"@9/.'$.*"5 '@.(2#18=NT7>G$!"$!",.7/!" +      !&"027E .J=FC5+( $ 0&@(I26$ -''"  +  ")$+0 ('!(#(.>:M!F\#=G144;0S'3KRrWo G& F-mL ˆN T, +gDD3I.2,A  B?LV\]H[@8D'4:-VR-BI:3;5.=09N?0:8;@;JC:W?&=:%GD(YT5–n2IH*J>.IG?SKMY_=L`=]eILXE7CV0Ac6D;??2<>-;8./3*,*%,0%13+:@-4:4/!**"$) )('-"59,7912<4099(;;.<+;L9D\R]‰F}©=t”5ed>F?c;@i-BD37,,1,)016F:FD6AJ6CG3LS8_m1O`5e‹A[qHe|^]…ADY67O1>E7?\D]€L\€BYƒKLqUemJOeLEOIEb6EZ1D\.>Q*;Q.?O9APFI]WO]HH\>;[A=]DToXr~\n€L^X83E3im9˜]:(.C(8O6[KNkNck?M`:BTIm€P{…Ol{PYlWI]@>C/=B>;HDAMFIKEcRRYiƒmªþåÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿŸ³ë{¯¹t†{ZiTGNE>F904?26D5,5:+-:4/97-2.*.'$+$      + + +       + + +          +  + +  + +  +      +  + & (!'%" +  +     '3>&H4(>=5%:>"!-!1(9*43#!'$!"& $+#"$$#    + + +           +  +     +  +  +  + + + + +  + + +   + +  =/!+,2,4#8 $0!3()-++'""@30D!3<# 4'##G',CB<827); \%h=f#1* +: 92 +67 +6!I-H) =: 4*'6!>!*-5!(,")$#2 -""5'  !"#    ($!+""!!"%#!$!-(#-<"#7&18 ,7 78&C=*<82'/***#!!&.) ' &3)AK.6F%`E"K?633,<3%9O%=4%5EG*6*%;#> 2\%AT9O,C-%U@.a<5[)c|0aŽ%:_(6'#' "$.5?BSNORLFW2Wb&AQ1-Q4+=.,05*55 /),40>]5\_5Sf-N]4|sK{œKNY3?T06M:XcBqzOVgJHXI=Q6CF38@;A;6:E8>E1<=,5=(59#13*:7,3E2VO.9>%-5))$,+!10 72/76*-7..50(-200(XL9JFN9>b7Vt:XZ\€Fg~:jp>RP315'+5$22/07B7@I6B>5G61?5?T=;Y3]yHTpZDaYZ,>_$AP&9J,=O=TfH\lDL\G?W87SKE]it„g«†]q€AFAiAXˆaCUA738D:>JX\TcnIM\>Pea•iáU”›Zh{JFTBUa6]Y9IR6EK?S\H\fMTgoeœÿãÿÿûÿÿøÿÿÿÿÿÿÿÿÿÿÿÜÿÿp€Âav‘TefGULLR@OG78?306+1=06B55C9;G0!&J4>:(&2* & %.,)#3%&+;#?DDZ67]8S%# (;'" 67-UA=K?FF >K*(C=+.'(/;* & )    +     ! %" !&    %= @ )  +  + +  !     +      & !&" %(74)'<%-4(7"37?5:2H,!<5F=*E`6\1    ,#-,/.7I8FIGAF79@,:6.3;*.<,&6(2=0@F)@?&10!/3#//*;7.:6,03()/'/2!03)190CW8EO<>9G7CN?PZ8[V1FM6^4>I+55%14*/812:A07:/80*5-+7//7-.F>AeFjNZh=WbAXcRXjKT[GRa;?R1;V,BY)N](H],LU.@P=NcLVrEQf/KY.CZ9DZeZ‹ý÷€zsSQCPU96D238,47/;7,902:/43)*/$%'%"'"' + + + + + + +  +   +       + +  + +     + + +  +    + *&$    + + + + +      , : Y,I<%3:4.*3$#%!%!"( &%)"' "&+++(    " !      +     + +  +  +    +  +  +  +   '$@,LT$?Q0 7,!'O2#GH=C!$=!"6>!7R#"LH# &62*G%*)/)2&/P(9R1?M70H;+81/+ 1/#,,44<9"  )!"*(+&4)!" +  .&& (%%!&1,8HGH)BK/4HC=4#!'""%'.6-N)'G",*"6;-R1&G."<%%81"D2/64-3/;B.5L5-9":!0"#"-30>@gGF\.G8 ")     +  +     + + + +       + + +         &"'' "+. "" 2)%(?0G+\I- ),&!)& K>T?4<.?&275%1A+44$4G*634:%" #(/'%&1$(/I(6S0*:7;IJ]JRqZ\eCUE15/&665@9E36I5G?(AB/B;453*2206=/:A?G@5I54H1391113//$*/3.89;I34>';7*.5-274=@0:?(,3%35'=;'27*JE4JR2JQ-W\-Ra=[fbW?KK:AM*?D0@H27>3lM/rD+7/'1:*6:&7920@65MKAfIl‚U`|’q¾†r˜Rg‚S`nIkp?n|OlzPoq>Ww4mz2W^+Q[/\t.Pn6Lf;RlAMdOGmBGb6MU1G^:JduBqøG§êP†]>OK:AkYV{U|Wº‡:GBHCK^C_INnQq„«z®ÿŽÚÿ…îÚùõsTY547>385-936P95Y@:XGKjdQ€ÓÿÿÿÿÿõûÿŒÿÿÇÿÿ±Êÿn’ŠW`WKZMOVCGOK5GC2D<4G17>0:?01=3*32+43/40/6,36-0/#*+&')(   +  + + +  +   + +     + +    +  +  +   + +  +  (&!$' ! + + +   + +  " # 4=%W/!KD+<=;&1- $# # %!!&$-  !"    +    +              +     +     +         +&9)C/<;/5A@*34.!,/L(!IWI@UC272!-6$,;2&"0!))+/%* !$ >92GB5;2!8*<098>D8HI8)0)*'!'. ,%*-,!"!!#!"!"  %  ! "!%#?,-0.;25I=01E<-F9.=2$(* !   ! ")#7""*%#6!$1(&. /%$/#..0+9**3%"*%!!*!6:=J7!      +   +   + + +   +   +      !" %(#!$ /14& !83K7?3'0$.,*)!'%,-$3,&5 ##+@:026/$B53oM'QR7PKR:EKFPK[^3e\j[)Lh,4=229<742-+518-)/)13-.77=A<)65(56(-+/8-0<$:?"KD7@B<724;%1<*.;0+8,MX7Y9Tp6Ld2e…5x…C]~JW|?Hj8@R57H51C74ECFsXf :l~)JO.?G.TY&CH&7F49PNDmWN{v4\=egKniTpdRkZmren†ei}BQpLb?CXXP|Zxà^„ÿV‘ÿDŸ²:^39DN^Cfír¶ÿ”ÿÿ§ÅÿpŒÿf›ÿb†ªurejeMCTEFP<>M89A?-;7+55080,<,-6),/,+2),44/5127+./)$.!)- &.# + +   + +  +  + +   + + + + +  + +                 .,#%$ + +  +  +   + ' '  + # +4 B)F/$E>;>8C&05("#  '"!&$$  $ &!!'"                +      +   +  + + + +      +     + #2F:!:P20E: A,!,+!%*17S>WS%J>6*1& -' '&+"$(:%:-$D+):"&4(*3&644B&49)" !$*%&#'($& "$  $   !"#,)<>TE#IJ&5AW6*6F1*83-8,49!*+!-%% %'(/"!!% "(!#!( &&%(&0   +      +  +  +          +     +  %   $*;7;2-)/3+&+ 'D0 !!$#! #%$,)%3 0@%L[4WtCEd=a=HL6MP?esFQoH@\FQXFGG.14+69'04(+++(+)'/ 0-,:755)66&(-()*1&2/,28.=9,B5534+40.4+1<-555-:3-60&23'/*/.)2:2Ab2Mb5Vg6R}=ZF2WR4MM+@B,=;(64#1106F.F=Y„9QU=K8@VCH_;5P'3I$:P1RWG?O=0GE4DP>VVQb^Smng‹iR‚jQ|Qd€T‚]›H‹”AL=6G/:I5]iLn~_`h‚6Oq2C:/=9B\R11E'-@(3?%0?):E/;IF>O¥r~ÿt…ÿ\v¬jm³S`»Zi}ey[hsLX^COZ@=G52=,-91/4./53,5-*4):0)-1(/4-)31'0.&-( &%",!)*   +    + +       +     +   +     +   + +     2 +1''#   + +    +  +$ &" + ++ ; R'J6#G:2>=7/3.(%"##  ')##'$,! '!."                     + & ,        +  +  + +  +  +  !7&14;A(49/'!("&. &=(34%"0( &  + & "6#!*&%*,#% ( '.2<*9!&"(+8"5%1%-2107/3'"" ( +"$## #!**1,.+3?8(=Y5=]25T+,M+9Z4J &"!&! $ !* #)             + + +  +   + + +  + + +             + ($" "(G9 ,# !"$(%%%'&"(:+;Q'A`/AZ1:k?MA^bLLTe>NO5GDI]@W^7YU(A;06;(07&"&%#("&(49/?E,AN,&1'+'&0.';=1N>603766-30*43,/813G1>D++0)38(iR+eE,H>+eS0fh5GZ;1->C1PUHeRap\OjRNmU^€gn¥‚‡½u‡ºd{»Mz¢0?A:Sagth]}Xq?”s)(B&1D6_pITtKLnDJP3JI/DO4PU=IYFY]dWbkfrkxv^_cADA18=.4=(24,03)=6&:>/:D>_Uki‘𮳥•z”€dojejsp_lkVlS[eFTa?AP26=)58),9-:9+55(C6)`>*X3(H5+27,,-)'+%')""%"$+!        +!    +   +  +     +        6 +0&*) "   + +  + + +   + ! ' / ?"I,?6*B8488>)./ %(  2*#"#)&!%.")&*()!%!'(  + + +                $ !!I! }K)U1      + +    +    5@=-73%/*+%I:*> !'!$'%,9/7)     $   '&%.$*###& -(&3%"! ,&,-!&'*!*$/7%'9%15 ,& 7+-9*2&/%'&("$2 %1 )!")!!4#)=&%KM"@K&39",:.#<$ 5$"   &  +   !    +         + +   + + +   +  +  + + + + +          +   +      &"4)3)#*  $.!  !""&*,)((&-,1C7:7:<68:H9HLSXIRJFH;3==?ESESOMWC?G2>B/CD$8/4/2/!/(+47.7B5,6$C>&O<&::3;E,>D%GE-BB&36-,33.2;=A*78%6?:FiLa—9nv@hzJF`E.697E0=C3*-&H<'D71H=0BI2IR,Y`+LY'>C-@K450*25"%+#!   9.-""!)( " "))(!,-2,5&/' %         !(W- 5T&%#'$"  +  +    +"S MM=B3B..+&53DOW`',[!(D#&"/0/&?(*6521   # 7&! #) *5%.-(!2($(.)!&*393/6*/51"'1#18=<2B);$'6'4-'+ * **!&!%%(* "  &+3 '' !'2;N);& !  2(0'&#  #   +   +      +    +  +  +     + + +  + + + + + + + + +    + +       " &  !) &&+*'"190+%$'-1'T;@+ -        '*$/-74<.52&5A1AD/GE3B?;LDJCBFCG78A,/>6/@K1LE6K324<-<38=)RI)CE)LG+4A(<>#13-9B=-C8/K:=G>0?4,@7/<4,8*(1(-82?L4Wn*Im9If^OYoHi]JY[DYC8A+=A,6E#CH*hi5`~1pƒ7R\HBS@=WAGX0.>/-4-,9*!.+&910E,;@(.3(&3(5>$0;&B<.=A1AM8AXEH]@LL06CB\zOj‹W|ZˆWƒwEHBK56986!:8)DF2AO68HF7Kc6\^8Iv&/20'$6/,6$-!* !! &"&)')-+5 )3 -+$$ ! +     32*66((,    +   "*%689QJ;;MB@8812+,(-.:7%OL8S7,*>J9K4BAAMaW#,!"! + ,%2 "/(&'#%)%(1-$(-%5".&!&0 '$%')*!4#%211"-7%6.&2F99#)6(,-.,?+9,6,8'11$ "+++'" "7&2""&  @$!5;%,.!-2$ &           +  +   +  +  + +  + +  + + + +     +        " "#$ "*)-4!!+5;&5^8Q3J>55=+"$ 2-:<#5<,DT$D=,97>81?:>:CE?HF@@G89@:.>-,40-76)4@(37983==2BC=T\CUY.*9/5C1=02)/3)-/)+!,+*586BH)JB&;8,&1//925B5;C91A<;F58A.?E.<@0S=>_:B`?=0-+()&'2'+1)'-**.$).'   +   +   + +  +   + +         ! " #39%>*)93*)/,#!!!5 ,2!1.'22#..(#*'!$%!,/$0,#.4!,7%(-(#.", %6,2+            "!%*" &()   +;LL:IZBBL61T/I",$8)1C,:D 5*&-0&/#%/ 1C%A+(""#$4(71 +5"1%- $"!!*.13!7-57*2#.5*"66': :%$3$"449/!4+)/"(,1%-+"% 4,*62+9525&#! '"%6!)%"*&$0*     +     +    +  +      +  +  +     +    +   + +    $ (#!"'/8&?/ (0."   (),+,-(-&*,&0.#G37H5=KGgf0BP-RV3[f;U[9ET>2@9.7-.6,21'"1&#/$ *+.;69K47CE=SW-IF&=B/M>8R8U_2SU1;C,?N%5=-8=$6?)7B0<>*KJ#D?'7:+61.+,20674:;(40$/503---,'-'06-?<78;BN>6=SG>^W-SI2R14D031'25(:+T;8>DN->;*9&+..-133:I<=8*7=67:(2:429/>NL^eRiZ@deHqkGocUnB\pFUŒHq£JažGiˆ9U_/AT3Wc;Sa.G[,EV5GY1@P,>Y@BR]6Kb8Ua@YW5LU1F•=nÿhÏÿ¢ÝÀi†ˆFY2)=7:SKNgZNhbXvVhvTjt_kx–d¤©‘Å{z‘^QoZQcMFZJJP67<<+99+48+;78984996?/7F2+$:1',-*) ! ''%&& *!% $''-'"0$"*%,(!$&!""-,#(-%#(         + + +       +    (($  + - + + ("2I028E*4>".=1;")&)&#+.I,A.,0"3/+0"6!0/!5+%/0$'!1 $)$%  !%"' '  !!&)/$8%0!"*-&*5((''!("*% !#!  '3$C1<77#/('61$/E$   +    ++ "$!$"     +    +   +   +  + +   +   + + + +      + +   + +     + +  $)0 !*# "  !#$ -#)<""-'$$-!8#,5#<=:PTQ`9HSJLWUX[HBLA9=384(16)=9+33&6."72"/.5+1:4:D2;K/8;+,0.-='/D(06'69)FN-4;%,4'4='@A 31"-4++7.5S<¦Ž09@4GI<#/A'414C+BH.GR0JQ7Re7s|?±šAzi?2<>%.)&2%;<-KO9AH1103)/,(/,.*,,,E/?k?Ld6ACIVPM`SK\GKXC4CD2XOEuU9eSSrJDRQD`Phi6&:D*8?:@0/4>EOº=hÿ>|¬Ea8B044'99;LZM>a`LZkHac`pk\l‚h…´†•ˆo]]^V>TG>IA@N:9=5,30%2-58-9<64<33<3+=3)>8>GH+%>(%-$6E$39$#! !   *$  :'&&($$'9)&2)4 )*13  +       +    +   +  +   +  + + + + +   +    +  +   +  "          !!,.!))!&-"+&/*  "(')" 1''!"%'(.*1C6OB5B@8KK;SO?K<9@/JH*E?419144%99".8',6)0/+.448517=)DI"@B#--/(%H,-A27::A=,7?-J>F[82LJ3YH/RB>DGL€Mfq29,*3111',-)351>G@@UD>OQ6WH7O27@-98,5))%),AC2LK4B>9GGZFSw;D]8CN:7/;5+G6/C9;=AK:C[8BeEUiOcuJeŠU|…Xt`TdCJNB=E:6C84=.*3($/.4?4;?039+39-032/1#16+)'!-9**! 0-/#A-8A/&99$&+ , $(#-#&! !     4S,8X2N24@.HC!)+$       +  E+)'$)!  +%',)*>*J?"4C07,2"/ +1)(*% ""$!        +   +    +    +     +     1 +%,           &$"&.$&!% ?) (("&!-&-&.07;<+,;:$AD,I9A8<7)47@4G7>N=8K2;B,>C5A?138*14*8;89-EA0E5*=73MH38J-(2=#6D&02%,;!*?,79/1''+#('*&,,+6123(<5';7,EG14>'05(2F@B2C>%=2'C92IR>af?eZ<^WQkknTiˆLUV8<.78+*4J-G>,00#+8',+"0*61!2*&#-*'1/$-51<6@G><>K1?Z?SCQV2YM)?;*5951<;3>81@H@E<'8'2;/9<@4C5;P-_W+dj(­l4U@K2BLFTFXPH>C9=I=XdFZELY;AP4:@4/5)(,'&122>41>15;+1;,*4)2:7wMCuF50$"& '$##" !""))4!    +  + +  +  + + + +        + +  +     + + 5 +2&(  + +  +   !#/ 1%7% ?+!8/.3/-.%+$$ #*$0#(#$(%#,)&-50"#%!(,!*)- .,''2"/+#"!   +  +                         !!*'.%+8"1<1/+4*-#)) E?@*2!8,;=:;?H8V,75/350I2?%<.2#03;, %,,*%//*(5#>0) !' "#        !    " _9 ^n(7GA,-5&*1$!!   ! @1$1+%$   &$4/#K4-@4=@*GL%:5#83#++.2!2&&*-!      +  '?'   +  * +    +  *!9U#-   +  +       +  "#%# T460+-+"# "!!,('#% ! &1,,?)9<-735O1Ad5+A+'2/)B2+580>678A9@??B=HH5?J61?(1:+;L44>8$;.)/"'+.#)!&$'&!,.1<(>721$;;'@7-:A,JJ,/?00:7%3*-:->E529HJXQNlCXe6ek@[t4bx5xxBpƒYc†NiWP€TQvB_n=;L/Q^(1D8'7N&/%&2$,8&'4-/;*58 */#15#(2)#/1(<>,D6BHD8LIVoD‘•8€/gY2*=.-62,963F.,4$4>%BK=@D>4.6-5:1)46*3>,@A8P@@LKMTOAHK>S=?P6GK/=='#,'!)1)05*32,5.,7&+4(4-;DH@E787?*0!(#!' ##"('+.&3+)'(F%:M*6.%') '4),3(-4->22=;AB:5BE-=A380:75?=<307*0L3GD6F9:A0(-6-,7+5B@J7+.8('&* 54,,*+,-!71).26>@+PY,U_/@K/7M65J8/7*)/.!%-")5+:1(:0OcEbˆAp‚EQƒ^W‹Zg‘ZmŒ^X}OLwKDfNIlI3I8+C0/H'1=)-6%)3#*8$#4!,0//2&'-!.5+/5&/(69/$571D08N@Jdlnžs ªU†Š9<>*$0,,40)8219);E/N]+@O+45C6@nWllp’jvFBLKKWk~‰uMlM>L='46-3AA=EC4I4BF'40%&*')/+,3)+3-+3+38+F7G?:L91,%&.",9',<'      + + + +    + + +  + +  +        + + +43'+- " +  +  + +  +"',9#O-W@%:@-20-3(!')! !# %#&"*("0(3A#"5(!$ $ %''"!. &$(3/') #'(!( #%2"2*,!$!"24*+*(        +             +     !&*!&#2)1$E(!>-@=EL'HF28A)D13) /279 :.(3@C)6C&673+600&! **"CG-9B4%.-# *%$9/5"#% *"(#.+%( ! ""  $%MI!PQ>-87"*$"/)" !      +'D5/33- "! 1"//:+5 6&+7+?@+8.(/'(5 "-91-+%'"'),*-  +  + + :+/$)J6XCB`=QCHPVY) +( KA IH$D_LPNJ>Z5$B3!AC6b9'2(*&2  ! + + +      +  +  " : ;L.8%"+,16.2G'/8''),3/1:2/,*,"(!%%"',' $&'-00&?36;A8&/2'(-.)/3>B<2<6A<4=<.8?36:7?=-5;-6>=5>=5=-;:!.*"$.44A5>H!*)/3$:S%A_"?:#<7')>(4;,BR:]lMOyIYe;K[8T`9DR'D<%?061&?K3>T3/ELAbC>mHUzRZ†@p…@Rqe]vjNm_>Y:?Y(@[2>\52N(5?*7C 0@#,B"37#85 ;3"/-((/$94$+5*A@%))$#/(!*-#372@8>RpSj§i”’Zt^QL'5/%45+<:-291QX%,3+2418G1KL7AO8HQ5EF6?B76?8#;*!  +   +      +   +    +  + + #   -/0&+'&"E,@_#:F2IE*6U,8="*-1.,%/8!)-/#38=B /E*1B!1A&0E)6!#,,12(7#',<)%=C"5A109.B,8,(, 21180>+H*;:/!,)1)!*/ # &&54EI!8.1!   $  "A69@65%%  $#03)2".%7*>&*F#26#()"(,!-, /<(( +, 4" )2& 2*?1):%@0A_AAS<-J/7?*Sh9_s'XlE`+;L6I]DDe?)N:'&'+(>4:s\"5! / #. !! %"(%  + +   + "0!)7='9D$DG)7<#91'% !'+(-*&)),&+)4)+?-)3.+;.%0) $.*,7D:2F5=E7-A525;094,44'-1&3/(51&;97J11;)0'&,1;3A1-2%#!!%)6,@Y3Yf+9<.sJLe@JjQSSS‘‹NxkNSlIifwœpEulLjbUƒ\†§g{“b“•>YR0&.)'-4-A+1:/8/223=>7:;.64+:?2GF;KR>EQ8>V;FW8Y]5WR9AD9>E(19"/8,4;,68'-1+@0+D/1@+$% "'5=$?N#     +      +   + + +    + +  + + + +      + +    +  + + +  +  0 3&*)%      $ +5$H$L4*<983-7#' !&($%#") +(#'%$%#+$%#*$*$''* "#(#'-&'&*$%#!#!$ "&#0-)#,/*+-./&,6)'63!($$   +        +   0 :6/9/" -+:77& $#166HF6=<9G6-I= ,3" $, 5#-1/.7&B!$,*(-*'0-04,4<&$7%)/(- ) +<59@N<T^&/Y?L1F/8#3N%7>+A/9 ":0&'   %!#" !+ (5#+  % "%*&  :36907)&    !+(7' $*2%-*215%&*-(0;:2@,;!8"#6$$<)(3#6/,2?'.:(29,-3.2:3)8_9Qw[t~„hD^C-D=>TR‚ˆV`m~Qt‰`{TJX?P\9GP=AMHDUJQ_@JQ5=E.@D,;@09;*9<)26,;/+6++9*#7 $##""$(8.BJ)     +  + +       + +   +   +     +      + + +  -4$)( +(    +  + + *1B#N-\:)HC4+74 (   " !!(!"0&""$" %$&&!"'#$ *"$ #(#("#*("*1"(5)--,'.!!*  "            +  (*= 1/"*$- & %"-)#'/=(!:>57(;9/4F*.?')85/5!!," %'%!*$".&2+ ("'282!/E 7C#;B)`G`{-7EDZudqTYv-MP*EP*8T.Fh.+4/"$C '7T%-9&)+)&/2)45=H3AW1=E+4L+1K,>L,:C%:<$4;$&1()>.+@.'62-5<0F>4E3(0 #$61.0663C;/H22F1.3)?>)UH'JE$,05+>f9X†ZkMPD .G';b3]l=V\I`{=OL6B1792B855CAB[F:WRatofwwXk\8B,57(0/"-1$/,/'24%3=3:8542)65CG@AI@?RBC]8QZ:KP*      + +  +  +  +     +  +        + +3 8%*('  +  +  +2=$H)P5"[?-EI:067%'*!" $ #"!!!!*#+&%('##!#'"+./-#*$$! "!#&"('#!# # "$!$%%()!&*#"'"  ( * +     +     +  + %'+!""%#!&!(0$" !&57,&N*--'6*-1-)'9!-7#/=5 1+.'>0(+'%/&86)8G'1C(+8##33-938N"4I>#91#5$- "0 "-$$$  %%.,06#'   !99##=%-/,2&/!200;-/0/,*%%4$-+ !"        %)+%&(   ?01'&)     +  +      ,!5# )0(%'0(A!  ),5CAc6?04*)$$##%-2M9-'.(2&"-1"$/+ /'(>'!6R):,0%$ #-*      +     +  + + +    +"*!%"#-'#33174'%$#!",-77>O:;=,.3/#4.!) !+--'"*:/$()))(1"'/(%)0'7+7A+=E%-1 *+")%,)5>,#0,$).&,>&.622/(+)*,)-&**;,(4/1C/Dd:T^k=am3UMD_6=V8'/*!//"6 )2.3+3*$>)":'1A*8 2<37C4(B;-F#0C#0G)OU.>K-;J38E(.< ,3 (4*190)/0*29-7*&/%#/3--4.'-1(*0#20$0+KV3bm6ID>B8'.3,@/;J--9:+,134/5.143-13/917C=6F>7D@7JDAR>BS==G<4HBCW?IX9>G8=IB=TB>U>AI,C9#A/-bC*T:81"9?*7;*,: )%')+(%+/(   + + + + + + + +    +  +     +          +  /8$*,)  +%$77&=) Q/,O93IA>.9:)$*! %#"$%((., #,(')-$413-7!*3$)*#)%&(#!##$"!"  6-.!4 !!+ $&#!#  "   +           &(#(""%((!("!+?-5A#GA&8 )#$(""'#2315 3'&!(8;06E )?4560&!'#%'36!&@2+:0.2 !, $+%)."!##$&&'-*&+ 0$++-/;BD;&.%"#'34; A9 3=0=;F)17-&5'(2"%!/*-0.+&!!$!# )# +$# !" )"% ! '  9:*'(& +       )1=<"28'%&%%  #1)%(  +   2 P 1$D&0#2 =8!'L0b[NSJR ;."#/$$.#,'1($%,)4 +",(  +  +     +   + +   %"))-%46-/1,$'$!*)5'-7,6$-2"%.$%*#)% &+($$# "'.%"+!+#($% #%%2 *;&392=,('(!#)!(5$+!*/'$+%$#!(*"."#(#"($ + )/*(&%&1/*18"+!$  !!)&! ),+0517,#-'"-# 14'F4H:=?8=>::@>&C.$V.)^;-OD;/<=($+!%!/'%,7&28!!6& )%60*7E+(; %.&.*#","-0+9 /#  + $!((#>8-3'; ,0     + + +          %'"#  &#&.21B$51%9);06(<050$#,G0/H$$$.$1#$$"$'!&&/#.*'$,,#%!2$#(*(##,(!!1)%&!"# %!#& !-' %8!362/(3 .80(DB;)8\.2I+9K/$@'(/(4%,!")(81%- "')-** +     1&.'%%&   ,4"(         %(,A4)8D8A).-,64()#   % #6"41*:U8C-A8'2# $-2:.0 B0!"#+$%$ ) +   +   +  + + +    +%#%",$*238@+=4 ' !)(+-%*3&%,%1-!%3!!*1 "'(&$$#""#$)$&!#"#*)*845684)! $! !##!&%)"(-))"'/%*)!*(0. 0'%##(%"#&'2222-7-6;.=B6E;;K2BE$2?(0<',>&*:'4O/9*" ,).--(+/>=,8E$)1"" #7'.%6+(9$#."+$3##1*"/%#1'-"%&'#6=,@?-($*(**8$/:*03<7BD2HN9Vd7ao1`r8\g5L9JQ4FM2@C1GG;;<4--5*)I99MHG;L63.2-&'""'!/&$%%&"      +      +   +       + +  + +($&*,    &09&:-F/#Z5-HG=7:@))-!#')".!!1"'#+%-//6(-?% 3 +#%(%4293<#*H*#!%  +  #"(*.5(3'84"!B# &)      + + +  +      +      && *%$, !" "$&&(8()8*;85I6?,*=,..$'03<+9"6''!#" $ $#('%(/ . # &'(/)5+"'&  " #$ %' $!$#%#'&,,(85%-*''3$"&3*&N29#%=2A2" #5"50630+%('+#!$((' #2  + + " 0+(!'!).!/'.  "!          +    +   .%?2$1#%+#4 Y>'&   " +!  .." !" #-!&''"11-+'/1(0 1,1*2*  2 +' +      +  +  +  +  ##(%!(%$(#%*-*55;M-MB &#$%)%.)&/&45(63"(& %(%#*&$#$& %/ .0;6 18%)54-;-#*++#.%)%%!##&*%(!13#(, &3",E#?`!Yb19 07#7J,5K+=P,8A-;P59S6Rw-Ye(09*$- -*")7#-B7B:@!BHHS4>*5A5-8-(2!%   #)%&%$ %* %))'EF-GF(6:2-'-*%(,&-/,*445D*TS#\]4<##.0+3038,3:(/80DF-;95GPDFVL;ZRGlFQvJWvIWn-QK*45.(-,'-'+-+*31,9=3:2(0.$'&&+&&.(4604=22=7>J8@G74A<7?;8M6?0GA2A81C70?73=1C+-6+=4.B;3<504 $)$" ).44!9B <>5:$!  + +   + +      +         (8 !)"   +  *+!,"-#;(&<1&(=5(,<&(.%#$')*45*;"'=!/%  $$$9!&9$.4&$1$+( + %(*: )$/".% &$!       +                %$"%"" &!($!'5$*<21>/.<,$*$90"("&*('*'"7!!,(" '0!+'!""0!")!'"",33&# ,"34#!' "*'(#(&&"" "& #&('&,,02)*+0*# '%('!!"',(#""!7$79$1=).9<@3@0.9,(%#!'0*+02/.4--6*%("  !!(,3)%?;,FC27B-/92,-3'%$!("-2 !.+&) ''&(( ),"''("!")!)H!:4C:INCAYBB^L7fFaƒ7FP(:C'43(49+,03277'0(!(&")"01&+/*6=02:,099AL@;I;3B46>5084(35)30*.5(/7+/2).2(-12,1C6,]A/Y94F440%*"!$%*'-8,6C):L+7I/!"$ $%  +     + +      +   25&$0%!(     ! ,1 +$!#$*! ("'/+""'&#'#$**)+"#*,'18$;"%0$)  !!!&21K#,%     "-.&'/. +       +    +      " " "%&,"','.0'29*1>-4&")&1.17L<>P'OKCBGA;ID>@<76)"#!+&*#3"1-1#1""%$;+1B # #&# $+& &$",&'!%%/*  #+-'-1&./(60(/2%+$)'!! " )&4&2.5#%6#%""!   + +  +       + +   +      +   +    +       *8 %#$(("!$&(0+#6("4B&/0!-'$=* C9&.        +  + +!/2YN&@H:821>&7I3QR0?B6,*)5*366)73''))!*()/ 1, #$--#.9,1=9:X7/C22B/6<%$2!$%+' #! %"%  #!&"%'(#")-*)#6,.##"'$%)"&'&27;>UY0NF+>7 ,0'49,P7E^8\l7:P04G.-2)70'*0%!($/0#-, )&*8#@H'\E#,#(!$ #! !!"$ ',#%1"''+-($##%"&$*%//+28(+.#(&',$&-)/'.%$!5+86)380J=GY<@R:9K?(9?(:N4JS6A/)<0)71(40.50+7-)5%#" #)*$1--5/9?,=F,BsX=ŒW9Y<):/ /%(#+)$..*35.+5-(9+);6 $""*%$!"%!  + + + + + + + + +               +     2;&$0,&.   #'$$ ''!"&)'(-,+).#1 !!!")%,10.*.**2(0&/%( $    +  + + "',#  # $##*#,!  +                !% "     $*#(+% +'$,)* ,%"$$-)59'/0.B;#=-$52%0$)>0/C*(B-9&5!/"++%#(,'!$&!."0=*7  (*$!'+6%A%2+ "!"%**!*$%#"%'#*((!% "'(;$,'  ' +  +     +   + +     +  + +   +  +  + +  +  + +  + +   &)**2D +=!5&)('#'" $"!1 +    + %"3-3E8I.MI!Zd&Zf77[D,K/ "!-&+$1(,5+&4(!#!)$*#'''$2,$:?,683+>=55>)5)35;G3#)" !! 2*-$'#"+!#&##&'*"'!!)"%8*=`^`aXA3"-,.=:?078"(*'0*3=FJU9TC'>2(3-)5%"((")"(!()1D")/# (4*:Y!C/!(2.()!#%% $$"%!%& " #(+&(&#!)$$$)0%"# #&"" !%!)/0@1EN1>U?4D7"2+#.*"-4 -A //'.'/ */%*,!),"*%!%%!& &,!,/-;19E6>H:@K9;?-97*42+08(02'),'*-$,*% ' $#!(/.7YH\‚hd“hB^G.<5!2; ?8=<'7<+38*',+ &%$.*$)!$ ("''$# #!!                           +   39*"3-%/     + '*"+69%3%'%!  !&""!'! ('&&&' 7&&?'0!!3 #'(+&$ + +       #'%"                 '  !)"'%%##&"'"&"&,)*(1%'&$*(- *)'/-#)$+"*)",2,6+8+.0*#)('B-".G*3,,-     &(" '(!*'#6'!'%!#   L6"&6&# +!! + +   + +  + + + +  +    + +    + +  +         + + + + +  + +   #.) +! $-$'+4/!     + +   #),/*;A3HN2/A-&5.&-**3%'.$%(&!%! ! !& %& )$&+$;5"5.(# %/!.43A3?E8@I7=E0>A,8=,69+/1%'-)).(**%$ !(%*A>F\tis‚cJYF0.+*&-'/=):F,7<+09&&(#!"( $#!% !!      +         +      +         48,"3.#0    +"'/ (#:8)G+13++$#!"'!*)/.302=#@$"1)(.'0 ,  )$!2#   !%#%$            +    +           -)*#).'.$&#"!  $/%#1,52    !$  ,,*6694=49"$# /%-(/;0*0#(()$ 7! &5 $  +# / +,! &!-% +/#("  " " " !)$/02 -7,%!"%," !+-".$   C34EC2*,!*     +    +  +   +   +   + +      +    + +     +   +   + +     +     + !!#!$#02$579 " #% $$  + + !!-3)5B:L>@=:5:,03+/:,7J1-2##&$-(+0'(/+369-2=26C:H\D=SDAF+34007)''% +.0/(,,%('%,*&.#(' $ %#$!# ,D&8.-'96*G/VJ2/WZ+Yt3Fd64C#&+$0$$5%/@-695%.&-%(-#, #)!$+$*#!"#!#'*'1',8.25(59(EF*>C1DN+WO,BI=]i@nx3XU3FNB@P3(,) ))$-)*1&.4"50#).0/2,'$"##+/26@.9:'0)1)#(+4)37;C;AG:9L9BP7CE-)2,).'$(%%%&$%"'(($(!"4(=I7[VSgaUH]E,?-"''%(*)*1*-6(18(.8"!$ "#   +   + +   +     +    +   +   +      + + !::7$60'0  + #' 0"7 @#629,$//((%)  + !#(%-,)/ !4&-$"3&#-+/"3%  # !'",%   2&-7".!     +          + +   +  + + +   +  + +    ""&"+'#3/!#%!%((*/263.6-2.')'#!"$#"%"# "!&!%$"*-1%&-*)3*?4@2/A!520 *5+-"$D((% ,& '!'!" $, $ /' ."'*($ # !# !%#( '6"*(0# #$!,"*2,3.% & !   I)1,7B,1(!!   +   +     + +   +  + + + +     "   +     +  +   + + + +      + + +  &%!(     #%4;.,-cC2WO-?$EB)-+ +&' #&! " ! "#!$$# ##%2'4ID4=FD'@.$9.)?%#1%**.-7*;=(39 C@80'1 * "&++ "   #""')""-'"-13;39>36F:HU;7>>73C?:J@@HBAK@?M22.('+$((###"#" %%!*.--%B96YBIQPYRIDQD6A;'<:@A$?? ;6 R 3P!1E/;=$5;3%)./'%  "$ '07K3J%0(*""#2 -7'1=(?)B19=;&B'(%&   +% ">0'!54(&,)( +    + +      +  +  + + + +  +  +    + +      + + +  + + +  + + +    +  + +  + +   + + ! #   +   ,2-),! #/'3;*4SG&H<#A005$*/,"1"*&(0*(!"(!#"!&"%))(+63.;<-+>.&/0#*$," %"#('-7)05>'78.'.. 0++1$!+-$1-/;(+8 %0%-2.35.19.8=5;G27:-2=18?::D>9I@JUDDH06>%./#(,"*,"361.',.&--.A?=NJBZLF^E@A8438':@'?L'CT%:G#2>$8K&=P"?@" + +  +      +         + +   + !!&# 5'=."'72'/$' &!(,#-,3!>(=.(30(2,(&+(#%*( - , 3 -%--$) #.%)7!+1#!7!)' #)2&!& +# )$!* #&)%'-.22,3 7""&## + +   +        +  +      +   +   +     + &)%'! '#'(*,"'.$-$''""*&3460E5)5#(.//14*.!-'/*&1-,+", %-65(?$- %#-&.4+6())/##D&("    54'??$('$=(&/ $.%)" N5ET'*&%46&$-'"$+'&5)%2(%0$( +%(1&4!  + !#"#&)0=4.A7*0+  + + +       +    + + +     +     +    + + + +  +     +   + +     + + + + + +  +  +  +     ' "    +     "$(4=!-&"20/.$#24+.F*23C8-73*$%!%& )$$"0!"$$"(&**2?,=N2,>FAKH#6L&DT:WLAQ7DP8KN9:BJ:QCNR;69.38)27#:4&-5)1<&8@);804;BFAEWIBQF5H9*85)=L(;A)9C&=H$=A%9@)=H$;G#    + +  +   +    + +           " %#"5)A5.4.",.'# "!*&#$(!$"' ,%&,#5 B(E0%1/'.(,/'$!+5=6&A)@,39,3#$+%")*(,6(&4$-%!% )%! ()7&)#"'+ )!,&-&&"#      +   +    + +   + !    +   + "     !&)#""  #"$ &#&'+#*&#B3!@<.4&&+6,C-(4"$. (2&56:@$)802;(5,0/1+6!03)%0&% !$!!"    '-0< -K")>7<IK0O"0(66"'EP2R/=I9P/6 =;:C9B)-(!./-41()- "  1+ ,  &%($ 6,"/&+-13+!        + +  + +        + +    +      +    +  +   + +  +  +  +  + +    +  +   + + +  + + +     +   +     !%)5IFgU+P_"WO%6C&?L",<-BO$).)'%(((5-&(.#+,.,/!#46'F+> *,'0%'0!%"'(%/-;;P8_v&md.vh$eWcp&Ic?B‡(0 '!#+34;.((",47%6-#+ (+1'/9%,6'-%/%&."(-" 1),-#A7KF9P86=#8<&8;4+>8,A,-9-/C,-@..B*;H05H#'/  !(#& '$#, &  (((, , %,!%.#'+(/6!-6!"3((-)((-A(;. //!->-@C?UDBKKG\NF_KQ`QVhCFX%.9!)/!$2"'#)'&1%$1&&1%'2))8/)7,/=+2<,0=?7MGCXBDN@FSPOY>EJ,8?16;05=.2>+5E,:J/=J1NG;fG;cG@U=8D?,/3)+61.9/5?,8D'5D'0B-9M'<@%    + +  +  + +      +           +   +   +! #((3 ?, 0<-71 #"&$&/#)+"&"+$./'+!7H&D3%/4,7(+/'$##& -@;"9+=418#)4+ ,))% %'%$,(.%$1 '-! '+   "  !  !)/":$&*+ .2+*25)""1"'/* # *$   +        +    +   +#   $)(0%+!/'$!2)"/*&+>)/@'39&5!3%13!(>6$ &#(+#$,'4*/0#3@5B?C!2E,6!'2%"%)# ""   ' (0,.$CKDe'7^/3H*;?+9B/6?,)0-%).$1-%32$12+80.=5-6-%/')%! &&,$* &.",!!#'#$#  "#& ($%.-$, .%)5 %.&,&(1)0'*74,@>0DA,@T3IR?TYBYOG[.3E"&2$0 -,8)47),-!#-!%5#09%-:-8D.CK,KD26FG;RC;NC?TR?TBCH1>H.=H.:A*5;'2A09H55D#   +           +       %+%)2/"#3$41&=2-2(  &3!&/ #*&#"),./"1)%2!<)40#//.3),.*")$!' #/3$8+3. .7"*<,.312()# 1#42/-+.++#*,     *)+# $!'++>9&E441F):&#-"!+",-#3!,   +   +   +  + +           (     !!""!'&%B5#*-,!& '9!'4!+$+&(#!#(#''&(+/"*6")4(.4'8@'4F(%=(+%4/5*B<5.7!    +# )-,:791>5+GA0$H,*7)7KA 422FJ.:`(13P>:W"G+.<%!$%6+55+2.!*  %"$'#K."99-3%.3!88'/*%.&%4 *,  # )&" +      +  +    +   +                +    + +  +   + + + + + +  +  +   + + +   +    + "3'*?=086+96*7-2<1=-(-4(>43>03?$+("+)%-+,'4""- *!'3&.5!*#*$#$"#$)6 6>#GH77"%&+)+6$+M-D_=]QC^Cm€7«@„Œ2pe\$gL+KA%,/#"'$)" %' &!#('$%$("%!"%2*BL,>Q(7T&5C&'0!&*!$($*1!-&)/+&1+&5 (0)+(%)+00'+"&(&")$# !#&$)$%()#!+"($$0(*2%(.'-7.192'96;C@6GD;N@>O1,9# ('"#++ 2')0 !,".#+5)3:/9H>FQ@KW5CI5%4E.=K@S]\hfXnc?GR39L*#1> !     +   +           +"!%/"0)##$%&0.<0!*3,'4 , -(,1#&+, ''$.(8("2(?&!42#4&%,#"("* $"06+77"02'34')<.+5&,.#+-(,>(B4?8+37%.:"#=-"!    !$$ !$+#$)('229")6$,96:$'4(+%'+./!4 &#'+)     + +  +   + +     +      +"!#!!%$!!" !$$(+535$1#* 0$,!#4")5')5#*+:8%?""%%#1&(7&&2#,  $ + +  + #+-938F_8_%(;&4;6D8(!#"1 3*!(8'0&&3' %!"-.) (&7!$(%%&.>*$/K$J;)@E#GN!C;+,!)'>+,*4135+,$($)"& +     +  +       + +    +    + + + + +      +  +    +     + + +  +  +    + +   +  +  (-&*025(;>"EC)3<18D%27+&.0/:)&0 ->$#/"%,&)&&("-2)/)-&'*13)IH3YB26B%,:$"&+)(115D$06$27 27$&3++>,)@88N>SV.OK 6B9;)""'"+'#-',".#1B0>L:NZEQ_I64E4;C47K.@G+6A&):)29*AS5KaPJ^OUZ:KM*7F+=G,F?+D@+?=)5=%#+!)!5D5>!  +  +    +        +   +  +%%.4#"3/*>)53)!1.'"*#*0" 0, 0.)3 -*',/*$:";'4+C*$7-"5*'+&-!% 9=)7,%70%-6$.<,13,$3 &/,.318;$>=.,P(?+-''# !%'"    "'!&*&.'6$0!*&3"33"/8&,9)0!+8(616*7'0-*1      + +   + + + +  +    + +   %   $% )( -',&.  %$)/#26(7%* !"#"!* (.#2&-8,32- !,#) '     + 1/ <6-:4+43%0$&8 "4%00! ,"($$ *#$*+<7$%&"*^.' +*X814(/G><(4B#3/'(%'<')9+ 5!$+%+(*,% &!  + +        +         + +       +   +  +  +       +         +   + +  +    +    +   (,0;0+7:%<(3'74!4$/:"5:/5>!9<%4: -2/238' .6%0?*:!+!&*11(5D>Fm9lm-@H"653,14023/>MeqZ‡vŒŽj†u›”fpVNqˆ.Yh+4T;(KR3dC&<# #!#$ / ,;# 7L#D?*;'' *!"#$ &# (&#"(!#+%(!#-&$,(")""&!!!!%#!#&!+%#('-29$MV%2<,.:-4D-0E'=C,*8''4+29*163-;S?^MLZ1:G,)E*7D$++ '4/387&(68*=C:RJ=`HX_BBI94C59H38J08C15G43A0/=/6E,7>#54)2./E@2\O;^RCSU=AM-48)*5-3;1?I/EH/B=!..00.3!3?'     +   +            +   ##%1'3#,$$8$;3-+@.)*(/$6/:4J>B7/8&0/#72 *69*B,31$=&$9,!1,''' %#(< 9)1+"/9$:,-0")#!-%%($#!*+#*2),70>34-"  !#!#   +  $!(! $!*",()**%*/7$46%*=05)2/2 +8 (3)     + + + + +  + + + + + +   + + + +  +       % "&+ +&/4 4* )!*! *&+,"0()!--$6+&-&)(#!#"$"#%"#       +   A80E)/$%*! $! $(*)  +!4"&#*A*3(;$5 œ/ M)*#'0{6(h`)HF8",'*)/% !#      +  + +    +     +  +        + +  +  + +          + +  + + +   + + + + +      + +   !$*4!9%$'')""'.&)&(1- 3+*7*4;+%:%!/(#/'!0##$+$2,(6&(;C549V7NE6,% ))'C6.AI$QB'"&--,.9)&-C#4S#=A'>*)31->!$- )/)>C#9<#FE.9@14=B4CR5UB-=>@B5+A@(3;-08,,7.,>+7A)>=1C:Cu\?Z<_K7(--".&"!(',-/:06B5@T$FM!CI!FE$DE-   $  +   +           !"" #$!,#6*47(+952&-C*E6 J>"C;(<<)%5) )+")(&+);%!:(5.&<##@,$9/"9+"''! '5 ..02%&0')())"!'$%('(!&&-+'0' )"'-!!     +   "#%%*)) "$"!#'*'!'''&"'!"!)     + + + +  + +  +      +         ##,*),32"1 %"#-%8*0328 2)"/((9/ 31&!"**.317 *6'3*# + +  -9#!<.1+%%)1(&''! #"   $!7E$99 (8#"%#$,?$of+4T5! ‡W9nfaGCJ '$ &'90').0(&         + + +  +     +    + +     + + +  + + + + +     +   +    + + + + +    + +      $"#'+.11"-6#, + #*8)*.$(*#&##$( '!*)+"3%3I2.J52F,/:>2F;-<+#1-%7),,EROLCQ@flKPgJdV8BE5?7/L3' %##>9N:<. ;;+)$/!3'.)4$/%0*/?$+=%'1 !)"1#&$$' ($#%("&%$(#/ (, !"! !&$+?32(*#,KY7OT>O\%:5!25)EB$33)$-1,2.+8"-6(->$+>"+*&(@4FO:GQ/@L*3A-(8='8;0@7:K1/B3VO2+50/9((/('7$*3("-1%82(7:DAT‚fZjBZC,$#'#"+$.+1:5.<2;L/;O-EW0D]4   +      +!#   +      ! !%&#%0)5211'1/0:+*F1!^?(YH,3J1!85,2 (("0! 7'6'%9&7(!3,%1*&(& "'%",-80!83'=;&4@$; &-$"+#* %&&&!,$$%  +     #&'!! -! "!,!&+ %+$&"   +  +  + + +      +      "&    #   + $%'&33+3 $7(/"4")/!.!,&!)$/%&)*!"("()".+$'*!"* ',78&8 $,!$ + + "'%""9% "  $("# .?/'LX&."9_JPlfeLNE'&"   +   "&0!#            +                +    +    +   +  +  +     +   $# !&,/!)-&(8 )3$+*%&!&%%$9,:(,)37 ",+=:>A0? &(6--5%7.4;.:?+DG(/6"(./GA0DY@;UG4?G8B?7WHJZ5NZ.Oh5Kt)RWKA=I@Is:^|+X`*7:#)#- ,*.0'-)'$)$*"#&()"$ $($!"& % &'&$%%"!! #! "#'&! %/'A1,F)H]6isVu{E^iCtu-fU30H-D= *5#%2#&1''8**8$#0&,*.%9)?;*?@8H.?B'1-)&*'.=74D4/<6-I160-%*&&$)"'%$!%+'+7CCVƒks‘hFZ='*'4/ 520/#.-',:0:>09@/?K.N7       +        +$'""!+&'*(1,#,*)8/+?0%M3 S?,>G4#<>%6'2+$2$!5#=(:) 5+$,'&$! '#*+,"822E%)D.*:5"40'%#$ !' $+       ") " !! #% !      + + + +   + +     +$ '    + '$( $('##2&'.&)(2&+!% "#+(#&%)&/*%,!"+*(-#'..$.%+!%+77&=' (   "0$$  <#"*2@$3-*$ ' +! " !$%9%+ #4$\4gSC93`PIK-0' +   $+(.$1%  +      +      + + +       + + + + +  +  +         +  +  +     +   ! &(*6,-5213/1$0&'+%66%.)%'1$,!-%- &&(56$ES!@D-D &C%2D'#@!"1&2%%/&)%.7.IO7fl4X\RP4DV3RU2LK1FB"2.#!"!#$$"( *-4E@Zrij”hHnD"5( ,4!-:!47!18$59(6>+6C,4E-4H-4@/    +    +  +     "! &###%.!$))'50*C0%?8)D>)5A:(:7**!60&+%6!4'.(/#$+& ("%""($,!$5%'3-%-4(*,$%)'".(,"0*        !"&"'!!    + + + +         +  +  +   &("*'   +    "*1/!$)"!%!!2#(/)1<46.%8 .%!/*!/( ''"#$$,7*4%#"-&%'#"+"(+'  +       +  --2%"#3./63%&)$#.W4*ƒgOj]5,2E62*$     !! +   + +        +   +      + + + + +   +   +       +   +     !!!')(+3;&'6$#)$!"%!,9#:M".<&05#&-(0 ,4(&.*-B45Q',7%,!"6& )'')2$).")#,/*)9U6`\BjK3_=!;84\$DQ$F.*5((2) 2,=Q*.<("3$!.(5@+072IH9D7(*4=*SULmBJSI>+,)#$(#48';E&CM$8E%6@*1=*-=)08+$/$   "  +        + " ! $ "&   +#,)&%#$%!$/#-, 41+>:$@=$56-186)31#+%$"93)1'7"-$,%0#.*"%"$ #&)!&('*,&+(1$ 2&+'(+).*11) +           &""%     +  + + +   +    +    +    $!&!# ($#-## #"*(/(%?#!4 ,%.#5 1+16(73.3#''#" !# +  "    #! %% '-+ "4$&#%,62#+ !     ,35d8DZ9=6*/*&"!#!          +  +  + +    +                + + + + +      +  +           "#$$(!"!"-((0#/,)(2-#/()80&1'.0($"#($'#*3$1)8(4,%4!3> *.&-7)>!'.%&2"+!"%+7$/L.5G,3;'&"+".4%)##")6"*.$7;58C'15'4")40*6/.>Bby(OZ!==)*8+8HGDTJJZ/6#+0 -6+<4:C$',):@02A$3/398HAIQ9E;5CBA`PVqNNWAAJ75:'+,))"1.%!%$"90:ZJEoIF=):)#,$))!6:&@H,@R*:F%:G'9?%-4"(.!++" +      +  " $"  $!#&"   +  $&$%'%("(((&-,43!18*3;*/8)+/+'.)$)*#$"!& ,2!,(+!$;!5,!/%"/$'!%!%  "$#+)(!'&",!$,"/+(0-#/.)%"          +   " +    + +  +   +  +  +     "!#!$ +$2( $+)1/@32)$.#)"-%)"+5#/(),,>3G/5/&).,2,2)7'6"5&0$#7"+&&!##(!" +     " +",%)? !('./.I*C!  +  &)   ) & !   +"!(((9J;2@>(#'  + +    + +        +    +   +   + + +     + + +  +         &!"#",%%2&@= -7*/.'2'9;'&/%05*415(4"$-"+ '$)(3<,,@&$1&'-'*#."$-)0;( 0#':""%*#0).$*5!$-1>B&)813 -% +)"0D'@W(A>5J*/?&7P34SI,EH+C6 1$/498"("!"")!"##$#)%!& ("'!#$! !#  )# *11 55)@E(52.*'*)&3#2>=BM3m_"@<?6'.;9;I,C>+2=>48D4;I0;A7=KKOmRN`hQGxQ2N. ' "%8;$JR)CP+=E#9@,47.1;%4<"3:2=&       + %"!   !##'%%+#(&#   # # " #&%$# !%$(*..%(6+.'1*+%,( ,,!0322 +3-3-'&$ %)%"#&$ %"$(,*(!)+)!!$&$+ # $    +    +   +        + +     +        +   + +   "$*&!%%3 $+!/&"$'(%6.$-2&/$')& +++&5(*"(4#+/&':!6B+45+45%&!.+(3-$"*%!"!'%  #   +! (/'073$G(.%!!,&$$""'/  - '#        # -+(/1%,8$  %    +      +    + +       +    +   + +     + + + + +   $     +3 $       '   + +",*;)8)06,/(&05(/)#9&0;+!1-'5'&.*+)006!'901)&!& 67 84'*). %'-&"1,"!#"# !!"5&,&'#'!%%%/(6B%?F *!(#(,)1(1'$()"6!,$'!', 4%#"##&)#(4:31('/,-$+0287?06!5=a_CB-1'$ #&"$!"#/7&??0/;0(92)-&&" /1%*,7:L86KE6O?9=-36#%8:3NU9"-"*-$CH*:O.2@,4=&4;'/2*%-($6&06%$,+        + !&   +  " '&"+,%$$   +/ +#" !)" $"!!!%%&(0"'-(*+&).$-$%-$+-%,+$!-"#%&!#$ $(!%'!"#( %!#% #("(%%!!       +  +     +          +     +      + +  +       "%"& %(/"*,+&."(',) *"0*&5!%,!"% *3,<.731)%"! # ("-2+2;F.3?!*=25),>*7'1'4 )6&$ # -$ (& 952/903I+#3,'0 !-&=):;.*+@KC $D -<8L@  +       &(''0/!." "    + +    +         +  + +  + +     +     +   +  + + A*M: +:( @! @@ iasyQlo^PT  &#""   +  +   !4--1?- +(A=)=B&86%$,0*<'5C(-4%-:%,2'6/$(%'-$!# 1C+7G'4<#PM<^#>G)7%+ %$%!!!"!!",)--!$,2(91#,/32.B223#A;*EB/>F+$"4)/**4+%$# *!&/  $: $    "" (!1"%3($')$#"   +    +  +  +      +      +   + + +  +         + +    +  +--%5=n(:e. (<9M\Hw^Op3Gp?^•/, + + +  + + +  +   %#'0*-5)+"1<86G29H*"*$!+/&74(($2'#0# *#3 ''*&1,14)538P52C-,;91E$&'$#&&#)$)'!,!#.,6M%>OKP23/)+',<)*E %#+25.0(343!#69,4)!0'% '$7=.0 IL71CC6^B8T;2X+(8%)5(1'+;V8?[C7M2;K&!-1>#%+%())1*(;10)60&-(!2A &#$ #'=5)=1(CA2IO,;@/KP7SV9KU8NV+D83>K2LH%BC%00,#7".5%0B1BMGSMYqHah7>F4:C.49+/54%2=4ADEM,X_%MA&)/196I[Nd|aamRDaA4FJ)?Q'9K&/;#(0! +          +     + !#") +   ) #",!* (( !".$.9.5%.6))6',1"++ */1)2%;'G$-*1+3&6&/''.' & %#(& +     + +    + + +   +     * :' ,    " =9.5?(/:C8D<<6(1)1 ( % +  +"  *',-+40&%!+$$#"#'!!,",.!#& >&%35'>B$2D 9"$+% -30!%!&'&*-$!!-).!,"%$1#%+(- /  !     +   (O'JD9\:8+B4!#$  &%2WA*G203/3%".!01,;='"  ' #' 1"3$      +      +          +      + +  +      + + + +  + + J /82R'?&K%V#Xn + +     + + +   + +   + +  +268 +2+'7&(7,9)52,9(12,""")+ &-$ # #('/!(4*%4."+74;.$/)"/(2B1@5>#&;$&$%+$"10:?3L\6=Y>J%>T(2>$0#,)A&=)8 ,7$ /H'1G/2,.:/$*-3-5$1C%A\9Oa&4?56A.;D,=;23+44#>E7DS8^u-X[(oj;IM/*.!%" #%/#.>(:S*MgLf@,96+22*5-%+(!$+$*;+ =]#/P-&3'"##$&./-*:/! !')!((&,##)%.*$.-.!+       #&&#    -& (3* !% 2&92*@) ), *#+! &10(800)-:C0N!,/@4CA#0%/5@'4F-; "-,"4       +               + +     +        + +  +       &"0     + + +   +  +  +     ! '.#',/9'$,'%&%#-3-*+'',(1>":F!3;$*3'+"+"!*#3#35(?L3XW:B""()!"##1.6"*$.%1'9L"DM!+6,.)-(/="IJ;Kd/[g&LQ*Nf)G\)|†OP1A)Cb5A`<:7)3,'%(&$)%)&)--0/7.,>+/9'..AI&%,1"/.!')# !)).7@+>L7C]:5O0EX+M\(Yp)29?XO73!)074F]8@N *3 $) ,1$4;%...#36$$(2/+/)4>2WS,;I!\f#Q_!3<'4X6*B91I7Rj.I]9`u:qŒB@f&2@0:F2OX0D\<_|Hh1K[ 7; @9!WM"]FG;IA"6:$'/%'1-.:-B@5=LAWm?[s$X[TI9*D7,QF&"'(&:*2J:Aa@Cc?]TTgVRTSPaUzx8DPC5e&,F1%*A36),B6+8J<0"#4=5I=Q*;E@=@&-H#7; ;5#)5 $ +   " +'' !/'+!4 "3*,D%=/#""(0!).(,'!)(&)$!! $) $+-!$"(#$, .("*%&+%#(+50""%      0 #  %     "@Y.8Q/4W7-J7"1+ %'<&(/:) 5%)#(#).,/(*?# +'  +           +   +   +   +       +      + + +     + +    +  ) & #   *:(4'#,",'  +  +    +       + #% *+]B@C 4C'6M.4KD5G5/H3VT/@9"6<+0>>,0 2''+#)"# )&+.24)B>7@25;<O,E[21]!3B(9-1F2EO,!5'7H&BK )'-717'% )#32"CNBL#4<3Gh65F16G>+P4.B $)4 %"$/#6;6M7/PC;eHLd/Ic)1G%1I1#>8$CO)MG1G/lu;!/007(>I,Mc0R\6QnCTv=So3c2g`*CA78A/),*("1B6RY:QUOZP]QaYLjIhsf^wK][=;MB;]@JS*M83*3,($#% $."'7&/6,2<60?-8<%2<$75)44%>3(2,'00)376IDgmwlJM:>U;50#$ "%$#!" ""!    +     +       "    '# )(%&'%%(#)/",%*(%/&"".(""! % $&-"1#,2%-)!-%+#  + " %.5!6#!'         +            +  +" * 1 $"4K39++" +(/">.#..;4439(11*1G/G8+F50C=-I-B..1$$# !! ! #6!+12)8*#&#>*+(',7!*735/H;6^R!Z[HH>D1A4738)(/>P>DY"<.07924+=.3 1))3!-%%               (+ : +8 ! 6. !A-(/,&/-2%13AI.B)06 5E4+ *3)%'/2!- *.&+ " &&*.%      +   +  +    + + +    + +   + + + + +         +      *!!       +   ##%*,.'*>?-5('B?"<-/G*@G0LE9EJ52=41BGMa,BO-22+D; (#*"13"+-*"$.1!'* ',%6->M-3@0FM/F[*6?1)?67:,AT)0?!;F/1F/+/*16=.*:*7C"/.&)%$5#5D&0!)>G(MV3HO-JW.*945:(EE1D>*"2 )-%1$+$'"3)'802C07@3)<-?I#37(*-,4*-6,7I4AE1;APY}T‚Š\l–HaƒAH-RH^r+^U'UO @BIEA7915=#5?%9B+=@/?A':8,29.31);3(41*0-+:59WLd”sw™jJR?4[8+%%*33"$ + +              ' &!!    $"&%$+/!)"#)'*#(0)6!!2 #! !(" &) 9' ;&8*7% B& :'(*'.   $)#"!    +      +     &$ +  ( -*,!3 0%'! #(75$+%+*%775Q+&C0/$$),0#0'(7%14$(% 3(-&-- $%$!'0()   #C3@V+Q)6:8J08N*\G-FVCGG7.?014.1)'()*6 )5'-#*:=,.0*4-6!;4.+6',0#)7$.) "!$      + + + + +  + + +     + +   /9KA?$L./'3&4F&9(,?#40# & 3#)%#@#:*5?4I$*$&+"%.+!"!%* "%       + +  +  +    +  +     +    +   +  +    + +  + +      %$     $#&   &$##&$02EO)PXCB%EA!12&676Ie9G\4:K*J7LW.W_(Oa(;@34(2!&5 GI',)(+0,3%-7))&+&8@1DS(W]2Vj-=W(AI!C<#2F(/>%4J,Ee+LU GLJM#fi$vo(?8;:"G`QR"'2(,@.)06 /A1Vs5Ui3D`/,=!-43bs4c"#)/5 49+#EJ"NB&)(%40#/$086:Y(*1!%,'3$,A-/;*24A=YMMzU8]LS:(   %   +     +   +   #!""     +  + +$+#&' (&''"*//$*:#%/'*/!15)7+*/"/#)) :&A*"A1#4/,5(#)& !  +  ! !!         +    +  " &!#'" (&6+&( + (#-"  *1"5)(+,(,-(2#+77/5! $%*"($",3#//0+6//@! =28)3"#!! :%$5"9.$!) '$&*2++7C@:5!64%'#"!+#!11*'?/4$4/ /9"3;'(8"0&' &,'2"%+07.''!         +    +      +-( #&&!E1+./()")4.*!*$!(+1$"-2,&0)3,#%5   +  , %1!)* +  + +   +   + + + + +  +     + +    + +    + + +   +       +  + +    + +       "!#$+"%&!1,5'8B6Om6Xs+Sd.:F$GV/[o?Vo;IT-:J2Q_4D^>7\@5M95B%-?35"24%2A.RV>XEG-4*."#)/ 9<.]q6c†7x…4K\&K4Q]66?&(1"%-% 1-.7'/;-.>4+><&5,,7*3A5J_B.OIZpMjŠKfŽGgˆ?Uy>a}Iq‹OVjI^|Ni€>Sb@OX@GZN\fVT`OJW:J]4PX,DD',(2!.L2FA-2#&.6BGQJYlQ}\dz6P\4;D;EM4MU-QM,89:6A8?@76>/6<'**"-*)0*/133:;Ltnz¦}’pY†X;1(""+(&$    +       + +   +       + % %)'#&,*%%!-!0 ("&'))2"%,$('.!5!.# ."-$)$$+&+2!!$'! $'#'( *"   + +          +     !$ !$%  " !""$ ,* 7'+/>,7"2&#'$ !#%'%*''"0.$ + 5%+<#1 53B)%#&'1#)*(<!2$##&%(%/(*8$1 6.%-3(2/.313,;-7"-- )0!6 $))/%(+!%(#"$$$'/"*!   +    + +    +   + + + + + + +=&$0"#+&   %*1& &( 4'/! ;'"    + +          + +    + + +  + + + +   + +    +  + +       +  +        + $9        " %&!!!#&## )$)'*-&0% *'$KK/BRC6IG3O74J/3G(+8'.E*6L)>*664KW>b2ER 0<$(8`RLoHP`UOeVXbFim@K[RRhYUfIN]@PaIUm?V[2UQ#GA,AG0AD !*37CC@I]GWkFhQe|6_W)91)3/#2,#*.)*+.?7TdYqtq[Y]D6 1.+)-$ +  +  +  !!$  !""' " +& "! $$15#'!+ $"!#*(-#/!,'-'8<%6'7#-"%"1">%0,%!#!")%   +               !$/ + +' " *'*!%)4'/5->(@-,0&,$   #','$--#,..%+:.8&7!+%(& +:7&#+'- +3,,"*'4 '2!('"./10"&; 3&!+"8-:,+*>$)" #( &(!      +  +  +  + +         +   +   !      + +  +   +      +     + + +   +  +    +  +  + + +      +  + +   +  +  +  +         +&/'1OLJFE   +     " "&$ &/",%1"$3#)5"%+$*1+B>#6N5=Q0:J)/F*"1&!1-&76%Ro&LM(R]$;;+*7<>P.KR7AL8IO5_hJOq=4WJ!B*2."(XhZM|93B3,@P1MM0I86I59P<2G3#/%('&"$("$( *9 ,5*!24/A+%8"!/4(7:#:+"2*$7!( &%$*'%3'!*$*2*(3&+8+-9+/94-4=(;8%:<9P0HU20@@OqMhzOz„Z€PbrLQdD9KKGYGYrH^oLGaQHhYQ^>FV:CS4XT)>5'87>5<>ESLJX_MdOVkHbkK\fEBG@4AENWFBJ;@>3O>*G@)E5">2!0,.G@EyZigT]L@BI4$-'#:=94.+)*,-/3682.        " &  + !*#,(&- $+(!    +* %!!$*"'"&$&$!%!##&&*#/-!&4$B!G+L/'R*=-0#!*#"   $      +       + + &#  *,,7%% '#% !3 +$%%+&09,;,C#(8&+:.(1('85.B3)7!" #! ' $ # ('*&,%-/)"38%7=,=%$3!!' % "% $!++%>$+<.&H".$&4+&4#2'$+#"#&"!**"0/))+*/% +$!!" !*  # +!)'    +   + +      % +      + + !  +  !%   ! +   + +  + +  + +        +   + +   +  +     +          +  + + + +  + +   + +   +     +/)(8!'7    ""  $!'*'( !# %'%$$#%.7'+/@%-G-!4*%6)"6*"/$+''&".,+:8G[io¤Bi|2eƒ9NqA}Xœ¹G]r7k…>±¸A‹¢piŽwIkbAR?T`7ak6O^"PR)F`/S_-[’6aw9HtN4R8&5;5D\JhMVs4]‰@s’4]vONyIP`*'+*('-8"(,#5IL?P8HQ+LU,IL15=*2?06>13='*2() %(%,''!)%*7!-A.8)!$ !'! ( %/$!$'+..8'6@ ))'/=2@S-GP3H`XW~acŠdYs\XƒM^j:3=B@SFKiO^lOZlQV\SF^IHSBGWJdl5lk,mm0\_8PQ@UbLANQ;KK>NT;XH:G36;B?IDJI>XO7==3D>0D?(436BCT|dTdDB4/762658Q>e~Ct€Ihv;8T3[_@Yv0Ur=UlMdd@=;)2="[s1[xC]6a‚ETpV8WO=C<6:6S=$"/4,17E[\WcvOhyOt€FgnB`a:DF74975999?@2=4>C9BE7>@76TIaŠiPxM,7*"&.&:G'>O*>F$08(/? 4532(*'.9(:B!>G%;I( +   + !##&(% +!$ !*! 0)$ (()$-#$ %!!) ..( *)%&+4D$W"f2 dE+>B703#"5*"  + + +   $!!%!)%#     +  + +        +       +   ##(+3.8127'2$00&+)#."*/..(%&*/#"=/%/*(6"#5')<;/J%&$-..+%%-!(;#3./0:33:#8 / .&&#$& .+$7"/&%'(-$)!'9"'*-+#1*%!,")006)6*+$$%#%4'5, % " +))%%%  "'. #)  +            +  +  + + ! + +    + + +      +   + +  +   +        +      +   + +       +     +&6.H >i   5 + 3'4G26')K,C      %&#%& 52# * ""44"0B'CN!IK88!<=&Ik _m"ux&OO3.?5-22J]GwoZ£kUxk ŸQtŒhWk”i|N^„O;T:2@CZSAW]IeSJ^?AY8H_;?Q9>O*7A$)+-0>"'9$/9 *1&3*1 * &     %/ )015$16)0D--:$+!,B?s•Kƒ’Biq78C1,56',,&524JKWu@p‰;@H75BH8LKAV;BF6:N=IT61ALHfVs€`d}V]pBRj7[e1ZZ-?@-08/59.<>6=G7GI;]X:I@-/,+*(-,/124;ML_ŽkQ}T*2'"+/*9;*.:*.4#-5#/9#=E!>D"=C'5D%.9)3A-    +   & #  !"! & !$%'#$    + %"#)*$= 6)E#%Q$`1e9+3@9$,+1("  + + + 0(*6!3&)#'!     + +         +   + + +   +    ! $(!2)13!.9(&1()5!0!#*# 0.2A-3:%*  +)",4#(:$"0*(&O5SM!5O28909?G;:N+>0+* (#!*!"    !'3'!## 2/ NH W*(*$$3 )"0"+!")&%(")!."  + & !!%"6 & +%0  +   + +      +   +    + + +   +  +  +  +   +   +     +  +  +  +  +       +    +       + +  +    + *iF==73'G)%"38(#&2A'20$1#,#   +   $&#../5"/)1#9?VCAULdyXJ\8^c%{€!œ|6k}a‹ UiyHPyˆd„[iFaŒRKjK‚‘1ƒƒ1vk[‡¥^]sK]sP]tg[fJP4[`Y[eTba4Tl(M>E2OfT†]Z~>?Y*;@#::-1&;FBNuV_xOH[1IM/ET:5?=3E19O;G]23C1.KNmŒ]q„Xq‡Pq„N‚›N_z6CK/672B@3jc3KL;P[MeeLQK-0("+#'%#+&%=<<`r]RbM/1'!,( ,/)39)19!,0"2<#/;,5?-2B(9>*/; 0:'08&     + +  +#      #%!""$#!  ?#G+e(&`1b2^<)2A36!(=+.%%+1! +177435&9+*81+A& ;(#' &#,!   + + +   + + + + +   + +           $##"&)%"&&,!.3('7$. 0 #,+:!)%'%5)*.(614-#;!2'#/"1+ 00/1>?I0QD373AE5Q#5H&.I7.B.8!  $!      $*2(! !.1EB.#FK' # * !")(   +!   "'&!"!  +  + +  +   + +       +    + +  + +  + + +  +          +          + + +        + + + +    +    +     +   +  + + + +  + F=$J[WEl>=a'ci!L_ 1)'&'$+<*""  "!.' ("&'*#"   +* (5-3+8 FO.=],8M(:#) *-+ 5%" "'(!&-3!/8#& %/+'A7;O?DU9AK19K50N0E^&[d0OWC>MY7M<'?58O-S\'?E+*=:/LQBjL`s9Um<\q6LW+0@-3@?7M14C(>M@Us]Ž¢W©TŽŸ[z˜Zk‚Fnw.xr8szIŽLo{@stX€f]\.=>'3*(" .#-BB4=!3B$69),:02=.0:*1:!.7#/5'  +       #     ! !*%!&'%" "(BX%i0`<#a8*L@*D66A((=/).%#8;B:,30+%,E7-:038/5;)+B&!/.) * " $     /%')254M1BW>2$$+      +   "   !("   + +           +  +      +  +  #            + +  +  + + +       +  +  +   + +         + +  ; SU]?FZ;-G,%! !.2QSA)2#=9%1=1CNAE]Lnxr››~«©Fj‰WY‚P^m8D]BEZX€‹{7mS%367GLUtTlmWO[<^b0Rp-i†EqW‰žGoƒ5WkQU€&Vc)q€;^d>PO=RP4BW@M^-5E+1K96 $(-",9),36/C3'85-C>)D93'.22G+%21(:%,4$!&#$"",2'29#5:""&1(:J6JA?S=NV8KQ67LBNe9P_4@R/6D%+3+,7:@X38F(*)!/9$:G8VCNiJQrCUo)BP'IX5Tb(ER+Tf=sˆY­g‘»m޶`Ž·UЦV–¹UªÀS‘¦bŒ¥a‘©SŠ”\`{[DT:44$/,".."A10VCJzWAU<$,-&* *4'*"0:,GH)06'/3-6C);;&08(0.%%,"&1')4# + + + +  "     '+$!$  +  + + " ++CY'e0"h80N8,E/*N)1E3!A:&-20'!&;:J2J=6K;7KD0:@*/A-83$352837C8'M",&##    +  +   +  +      +#)7)-####,("*<""28G?%N&$,!!+ %*#+4#<**%#!*#';%,)",*!#$*'0*'6% 3#!.#*&(#!+)5*!1 "    $#8"9>2H15$<*5% %60% .:$ & +      +           +    +   +   +       +  + +  +       +   + +      + +      +  + +   + +  +    +   +      + +      +   +       >LhŠR{ŒVew0gk^? +WA P>rnDHiKgM'"!%%"!# (' 2)%8 '0%(##(;&*='B$ !  )3);=6BT>F&7A$NN.DH8¥œnyž‰v–~e“<@^D-H>%4/2>B3Us(3%,,5#0HYmFVm=Nr=Mx;JaLt’lf‰ma…I6_4C]5~Gx`SeDTvKYˆ8lc2\z7Ff(9P$")4)4!-!%&)&$&1#)#/%&   %)"($ ",)"3'(9 29'*!&05,8B*@B/JD-E;0C>-CI5SCAY'8D%9= -62$96-> "% '('580IED^CUx>`s;Wu8Nh:^}7iƒR…£Y}˜h`m\“hr¤^m£ch s¸t‰³h{¢k¹g“¬ZZfHVZ4FF*KB)?=+PA;_NPƒ\?\@!(-*,.3:;%;>5OQ0:=&&%,(,-*9)0='/5!$',$.3'        !     #,)$$$ !!!       +  -M\+b5$j5*F=*8.):+(F2%<85526.')?,0J$&N;#2; 46,273:1?<,7R);E0?H&6H26L.)?+&<$(@,%6,1!('       + +   +    +    + $! ",0&$ $%$%"%"$.('/"20'BBA"~€fZ„G„–_ŽŸ\‰€gr*?*&" !##) !"  + $ &('$2!/#6E-BT$#*#*"+7:;BPS4N[2H[0O[.[^5}cEO}“claƒs[lTXl337&2F;J+):,"#(; $)8@AVeD4NK:H>ESDAXa>WaJzI7F(E\JSoeSch9ZDXdQOZL*P@':?%:5%3",(!$.&#!  ")1 ! #$'&6#,81:'&/'*0.*564C+8@/EF2CI?DP3IS/6@%*3(*2*'3%16+-16:A&3?.=Q52/21)((%/ 9*28 !(, !#2%-1 4=#>G55J48H5/J<&;3 70&*0(4(!0$"+(+ ()"!   +    +  +      '("65.7(64-340;'<984D&<$+* 36#59"8D12?+$:#.#"$, +  + !0% '' !     (# 6(0&&& %! )+&7+3!5        +    +     +   +  +       +   +  + +    +         +         +    +   + + +   +  + + +      +   + +  + %:5K6>BD0B&(I-,@83,A:F:@D=m{JaŠ>`UO/B*;9( . $"  '%!     !! #'@B ?E(?E&-7",5 )2#/9(5B08K7Jc>^l=gn?"DC 3?%4K"EM5=#7H#@Q*KW2I\;Sh>Oe7JY0GV@C\QOpQcƒS`DLd8I\CNb5Zp7^wQfU_Š_·p”ÂnžÈ`—¸[¥Àbœ½E¡—IŠS}gXoRJ=9,06&.4(?E.A:6LO2NF+@<$$*""!*.#!#!%&7=0SQ(     '"!&  + .#-(+!($!*$%    +  + +        #!$/(/!(/<"7#X#_0 m8+9;(%%%5C%=3)(.4*%'*04*)##7*;@3H#=;'9G#8>0,L0'<59*'&$% !/ +&# #'-"(&     +    +   +  + +  !!'/&&! 32 0;$58"/9 2?#4?(5D8@5G$1F)0@&7&$'    +       &"#.!) %&&"'!  + '! +$$!& +  $!*#%$#!!!)$!'$%#)$)"#"&      +    +    + +        +    +   +    +       + + +     + +  +  + + + + +   +  -% $"#     +    +  + + +    +  +  +  +    +  +   + + +~U†wmj9*6W(5H/A/FR*We-IZ8Ns//3QnL;^bbECy8[5.0T7AD*BT>Y $T("7R'Lc!9R #(#!&20'&+"%*&+AF(?W*AL*-;,QQ,MY#,:!)3%FH#4E% 75N[BWK8VC,G,4CFGXF2J9;A!'"..@< H?&=DPM?N#Pf%,<+8Q)LX58F,6=- -'!1$'27Qi.3>.-+(&)#+4'(9&   "!*',%!"     ! (, &".)3,:L;5J8?U/>F&-1%)2*4>+GJ,FL55GH=V_IrO^p4W_/>Q/BO/6G)4?-8H-AO*GK-@S1Ib=L_9QlBZm6Zl3N]9DW<>OG?_SPfCE^9L^=I`AZoG[wMh„FUqZS‚ljjt¤q“Át€¸u‰¸t›Õh¥Ä^‘˜TlR3EC&40!6;-WV3jm7IR4RM,02!+),,A;#.-,# +-A2(#,9&:(0*" (   +! $%$     +$ +&)" ' !*7!0#)%%     +      +            +  + + + + + +  + + + +  +  +  + + + + + +     +  + + + +    +   " +*  + +  + +  +  !      + + +   +  + +   +    + +      +  +  -j=q|"if2]&3S':.5P7;L?O4B4IQ5Sm)Qˆd_˜Lh|?Gp70R*Iu6)S,():"'/'-),23&## %12(! !+4$*+("$*4- )B:3BM0IM)VX@]v.?U"%0#&41(#&1K^29K7-5"8?%7K45B*$&&"&#!&2:>_BSw1BaB@L'AV2-A#K`0K_6Uq+4H +%+0/%(?0@&-.$$%!( #   "$     )/149?"34" +@06&7$38+@->C'>C7EVCD^ODUgH_lHZ`HGbJHe>DZ:?VQU{Yd‰ix¡p\…]bŒp{°€¤Ár•²]••5uv-†ˆ7„|?‹‰Hy‡BV^6>L-83#EF'YV+^j,TQ"5=;/#(.7);@     %#,$$, ( ""  !!""#%     + +  + + + +  + + ""5-'D /"-&.914&3(D)!B*$G-!?1$:*(+!%)9 !1) 4"'$48#1@6%@< 14"*&(( "/'-!6+#%(+'0(."0#+#     +   + + +  + +     + + + +  $' %&(#(0($1 016K21D/8D/4L20?'(7"2!)!.&   +   (3-"C4'*#&2*#%, ! +  $%.+%'$ !  ! '"&( *%"  #&",!4#%%( #    +  +     +   + +  +   +    +   + + +      + + + +   + + +  +    +    +   +  + + +        +  + +      +     +  +     +    +  + B85-",!I?!8:+6**?32K1Zd:Sg>RaAGP(9=# !"!B8-1"/+*,+7*:FDY*KQ@<BA!/8  &#            &!*0:H45F2+ %).1?0AQ9FSIH%ET#I?#.27      #(#$) &%   "$" $             "&$,-$ $&)%5/,';%K)#@0&N.&D6*3,,;& <'-)!)"  % +?.9I0 H5 )(%%.-05)9(+#**/-16 6'    +   +     +           !)"#4%!%#(.1)%6)78)1@% 8#!')&%.*#+)**2 +&;!") +)-/->%-) ## #% $ #"(*+ *!%#  $#&   !& 0 !&""!#%#" +   )  + + + +     +    +  +   + +    +   +   + + +    + +  +  +  + +     +  +     +  + + + " +) +           +    +        mG I3 @ R< $(##)(!"6(!0+#8H,(-9!!"#/#")(.""(# #"$!33+: 1!#/&+)7.F/?)"'%,"?E3L_@;^A„v+>/$)8A>,F;*>-XZ1=+8A#b_06"+58FP:Pw.Vs7'C ([I./G7 +      + "&7@56-+)6?:;A54E7:3(#45%:-%++./72>&+=%(;&)4!,<#A 0*$    +   +        +         ! )( *,#12/<->++@$93(0"!!1/ % %.&6,7*:%+4'.6+45"9# 7<'/'6$,7!4"%$#,-# +4. %A$%0 3!*+* * )" )' *64          + +   +  +    + + +  + +   +  + +   + +  + + + +   +  +  +  + !!!$ +#  +      + + + +  + + + + +    +  +      +  +  + + +  F!}YV€ˆ>›—*—›Fe‚$RB?3˜j$`s"8K"6J2%* #*&@6!9.Q'ƒv^7 _B$(%"%)$#")'2%.6%+/!  +. +'(6$.&-3%+13*:*=I:SOE€©j‡¤@p|$aYGF/$ ,$1#;,);TQ#A$".(2&EP#1$(3/9C<:N-,=;6O88> DL-`ea5'      !!&'0.=+=E+7H3-54)34;R6FZAA77&BJ85J9.?>G^8BV6>CK*:Y.NTK]G0AC+MF?_3PV*KI66JH3LSYFTk50D3/A,8D#=C!GG5HUPS\>7I8CL7GSI_~dy›eˆ­n›Æfœ²RnŠJ[x7SgDTv\c…Wn–ikˆjW‚b_eޏj¹j¸o˜¼_—µb“¿^˜­mЍoœ¶X–®EœH‰œV”¬R“±N  +     %   ##!" "#%)" +&!#     + +  +   +     $ #&,$1*0!3267->"3##2#4%!9%&4,&3()-(!*!####"?& ?Q1N".=!3;(69"6A->/#726)+H;6N+C+A3%+J/;/("&+&!-#$"   +    +   +        +       "!$  +#!* ("2&2,").%()#+ "%&'&!/.3$58"(=807?2=?>?T$;Q)6C!2B+8!!)"''#)&    + "'&/&%%"-$$#"#&"# -*y"UˆD{o ›]™tž»I@m:‚Ÿsš·XGW)Rg-Z_VOF?'„y;ž©)rG–¾{©T¯ÃOš£A7%2&/-&%3)51,0$#5+11"#00$54/)8 #- ok:Ÿ«W¥‰Lc{\f^RtFn”76H^;BdVHjfR{vbŠyrapLgƒEMf:ChOTzMj‡W`IQgQax`{ n}¯q•®l€®s˜¿s¡ºx’¹hаt©Ïr©Ða¥Ém Ãh´b„«`   + !  "# ,&"/$$ #'#    ! $ '     . 0( +*2,'8)/+/3396D;1D#C3+E+)>. 7-!4-!.)",#!,#%#' G/DM'DS1;H+1J"E@%7N+*C/*/&;14C8?3:N5>I#)M000##*'&&     + + +         +    +      +        %# +"$()$%-+/-')6?9"J 54,5C@L+3J'=C&I.#7//8,??$3K%?#%!&  !   &"  #& %0#   !'$%(,'#%(!  +   + +  +     +  + + +    +   +  + +     + +  +    +     +  +      $%!) # +' +   +        +  +     +   +    + +  "0{oUqeu)-v”ž…¥O‡Œ†}œƒk`?KbD9ZQ=[MoŽAadt~Ž’wŸwGx“*G€,;¥L|\‹.8/96122.$."0##5")64#8E",,%+5#)!*&,LjpŽ›k¥o“CuNn}\~Œb-F2881=CG#7A.5+ag7Ih;P1+0ENE@W1-3,ER(&:&!"*+04uk.L]/pf1]Q$*>!)*#ZU ~w!MR"}x,XgA8SA&4<        +     +# "!9-HF?V?G`FD]@+;6/0$(&#".+>FCqz>І:ƒ~"gX!)--$/2&6<,B5+<!!1//B+3#$#8#@D?V0'?7G[;JU3@E 2866 B@'4903<=>P&8;$%+ 0?;P?HYC`xPpTI`U@iIGbBMc0KYB:"8M!-E#)5264<B<#8K)B)3:2#=,+4+ 3*$+% (!+*""* B2ES2B[@1_9'D3$2))9)50-&&/03:)6=26E4-J)(<5''""$ +  +  +     +      + +                ")*#/%' '.*'# 4<>5F6?@H-J!)6#8.CSIJXDA%XW&=@ )=!.$*/1/2-"#1=,(-N+LHZI&+-&_I>iŽnBqzT|q[ogJemCxfAb(+8,#:7'G<)0/%6)/BaL^=.G2 #6E&);8-B0+/&-A>8A")52C5,B`2CUKmb>dDJW$BS*1Tf#QD%"-;ZMka0G?%<2+@*H[     !    :3:)5J5I810$%'  .!9Y=_tEvsMtiKl97C"OQ:F0QQ-a_"]PK@!8@(2>$'! 1#/)%1,><3I8C#8E&?B*F?,L/.?8%*,*1(#(!%"%"$*5-ND.3W>8IG6E6!>"(($#8"(2; :>)8I*.F29'#"     +    +    +    +  +  +      & %-2)9!,4'5.299+>&&.'>'(9/28/,A+1>4EI%A^ JV+\[*Uh3=R(<  $"!"/%-!#).*+'   ' &+57(=!*0!&13-4;*>!') ! ! *#$!J C,,/:99> ;$'!! ) " %" +      (   + + + +  +  +    +    +  + + + +  +   + +  + + +  +  + +  + +   ! % &1''2  +  +  + ( + %    +  +    +               + &&*10!&( !7%3X5X[9at&:ZTQKL,5(',:    + %&0- "-&  )(*6-.--$"0."JC*UX0\Y6e_$@@;?76"6,M%1I//W'5HMQAo€4YaEhqG]vTUpED]+5F$06.257"##+,*4/$=5,B47WA\q7L_AavNpˆQv“Dq‹>f{7\q'/?*:&%8*#,%#*1)2-7>,:0*)    +    +  +   + + +  +  +      + +   !&'-!) +, #$!!$).!$/!19&=-,7$,$"$$'3!!5,%,$*3!.32A;/?^BX(-H%#,!.# + +.) )!)*?K(H1#0+%"5*)A(90$1()"'      +  + +       + +  + + + +  +   +   + +    + +         +   +   !   +'3 28!+-%  + +    +        + + + +  +  +           +  +  $ /+,7-0#4;/5%/#.!'#-. $# $G ";/($EAQDe8RjdvNGh<-@PAnpQ|)]m*9[4CT4TV+WgDEc%\Q$8;(;<14I719!52$"-Qq$&0%)+"    + # .$!.;#20>7JO(1:"%.&/14033#!!#.,&.LL@apSt„Zvˆ\ŠJU\2CK?=W):O<8MK@_U`„ap’`qŒhu™^ToS8gXMu[UoUYsZfxQevHI`P`{esŒk€£jq—^x^n…T     % '%$%*  &$ + * +(# #6/. 0;.: 36&06%36%*8 (0$.& ,.(4#:+#58"!8!1&#",3/1.:-0'++ "; !,'"*#),)! 2)@ 70-1'  !($!/'0B(=&$6-&3.1/ '  + +       + + +  +  + +  +  +  +      +    +""'$&! !!%0)#$&,$( '%4:'H> KDI%($ *.(2",*13&*?0= :=A<RCRCN>\I"HPB8X4 _M 6Rj9?gHY?H-?G<6!PC%Rh%Lh9%S791!&8))#%"(*.$#-)2)=+)!4 ($&(%"(      +         +   + + +   + +   +     + +    +  +      +  +  + +  !%   " $13)2(2 *- ( +  +   +             + +       +      ?3$ !$()2,5#)3'4:.6B(!/!")&)),4843)9 #!8&!A.0FHQF?^[NVwt„v¦„Ov)L3+<69@%%5(%0/%( +#"("' -0.; #,*!ˆm-€£nZ‡_Ik„K¬i!,;*/06,:CLDEV<9G?',3$+Y5B4LV),:SDLB3OA4D13GD8S=8Va@ZFd‡FKh%6J''-$'*;6:4"")&S(6#+4#!     +61*)!#%'*'d_7nr:asH[c2Z[%p]1Å£,ƒf!XMZQD:3,('II-db$AC-:?J4K_Lfo[lqUt_\n>W]AZW;XZ1CK''/.3G@bq@]p@Q^G>PI1@0%3!%&'#'"$5"*-!251F7,&);3-)$!-+#2&#)-/&"0!( /55#;$#!5 68'H&8,$(##'    +    + +  + +  +     +   +   +  +  +  +   + + &! "! !")#(&*-*B57E-<*366F<TK"@]0/W<"- $$$D#):,(+4;2 1F?;":]%EQ.Ll1rb2|‰/x•DH5N>,7$"48$$)%"%$4$.)%$()"++$(&  #    +  +  + + +             +  + + +     + + + +    +    +       +"%$ $! !  +!,&+4#&4.2$3B#/   +  +  +     +  + +        <)>X4Ji%:(&**4"!0 $$'+.GE/34291/,- .3+,',$*% E2%JW;BI3BN@DQw6Jx.;M>;$(0!-.&+*!><SZEN+/).(, $KA5„¢yOŽ}GƒS/NHRLR@R=<#<@+1A817=ad1QjUd˜ehr#NdEa%&&.0BI!RH35:=J;29#38<%<2(D',0-1:2/9&9AHN'! ##kj&Gl/<     + + &+E/@R ZM <>9Ifii‹_PqbmxO‰†IûÜañÿbÒÃRûãGȵ:I\+nh/mp2}}Mm‡Huy;AI:GRH]ldƒbz‡fšUˆŒ^€‘Rm€N`r28='.5?6RbAbNHRKT_5BL!10$%%'#63>O*9F:?7; 0='0D!1;',/B:AO<3N8=Q<I5U`@^sS\yP\qCNb1*64@/XiE^kNfwGO[:=Y>OgEUsSl‚O[qKOkJBYFEZ:         %$$(',(-*%,&,$!) (!".+ ! + +  +( ++(++"%0!32$39'26.%;0,-'/.$30$17"(9$3*'&" =)*=;&;:/>+/"10 ./&$#" ' 3" 3>,6$$*   3 +; 6/*)#,&)" + +% !  + / 0      + +  +     + +    +  !  "!&(# $!)"+23FJ#HO43H%K< NQ#@U4-MJOAG..L.<>.5IP>67/5 %)2G0Xr08K.?%+&39B[’/(68Ki-"-# %*"?W9BP[tgZuBN\BNp69I-4(*#)5E[q5,@-4?/;H!#+$05+ %78'*7'/@*T]*7E@,@B"70-* '/8@Nd'!'(&%<3 851:!-B$/    +  A5K>7FGH`j>%2=#'1#:&/>0%?6BV3FN+@N-CU:JYCLeJOiPauDYm+G\&U[?qƒNw‰M`pIW\2IS8QkD_jM^nQTr>Mb5;P95N;         !"!#"*!.)&2!&*(#&!',"0, 04%>!1"' +   % +(*.-).)5 +7$67#;>)1?)46$?9$0?);%$();*CA"9N,%=.+"*08"/( -*!%,9 ! 4 H4!9Q$:F%5=$-70,3163-943%*5&, !5 1;'5$-" & )- 7 +   + + "(    +  + +  +     + ( +"(,*74%9),0)"8&.$.L&(HT2PX;S[,=]9=NG5?>_:*Qw-LoIK`SAmHKeQdeJQd:*J"$1!0.!@8#-G (9#7? AH%:Q'bL0Yr5?r81K-0/I8!_V)`j-Ts;Xg.i~:h~LI€GHD05e8%5*755R'<##!;(-C'6& 3%#+ 3(%$"#24 -*&   +      +  +  +  +  +   +  + +  +    + +  + + +   +   + + +     +*2   "   ' %*&")-"04#/! *:!*8+*7%&'14 ) +*.!(9), )    &5*;'27&:@,AG&@D.9    ' H& I_Yd[1: "  + &+8C*?V:'/@&&%/')&!AA6AI/3B/4A1CT'Z\9ck;Ha,9[/1=&+<<)*"!2*@R7G$*@B#79,-L(AG$&- * ++71 )#(6L9OhBLaMbwHFN.>J-:@+37'6CCS^N?QS4GfEbkZdyYwd\aNBBQ7AdPdtB]TDYahwB^[9SZJCUd`l[Zj^;\Z3PgEa8?@2,6*7F-1>.4F/G!4;/;">G&2<3:S<\f7LV1BP:CR7G^>JcHWoCLg9Pe?LdIHeQSrTaGhv4Oa@M_EiuGPiEJb=Wf4AM4>L1 +  + +  +  + + +  !# -,.$4$!)( &-',0*7(=($1(,$ + +  . )/0.+1 (6%.#7,$.F(*<0+7..1*,5(/2*5.'7/E.TGZ[,Ea5*O56-A%B&1.$$!& $JO2&0%$ GCF.N--<U(G[,D_EPLGPP,GZYf(Le,4=30<:13     2 se™2‰¡Z”˜L}J^l%-9"$ ++ =I!]V^ŠQ‡ 5€Ž%kkQKBCDA55&*"%#+$5'2$+%"0.7)@O8BK/:J$(5&4H'7C:(8N1/A=154E524J<4M82H7782-?)$9&&+':)"->)62   + ) $8# +=?:I*!F"*#  + + +  + +  +  !$1++- #!+&?7<@SI2SY1@bE8VI@FAKS2"WB"K$ #&*&%"" +%)%! +      +  +       + +  7% UM 7? +%  +  + +    + +   2LIJX     +   74 +DLC?7WVNLHR8\A$ +   #-!%$)%*+$,&$(/&!*" #('+'!,7.(3&#-" ! !'/-,*8%/2"3=$7+*1-,67+?A4HI39E'"&    + +(1S\9\z2\}sxnlœcb’R¥'r€|‚XR9//?K+5I*()"JJ.>'!!;G4EV6BK1CT=TaRTiLTk2Q;8ZrYbjLW\=ef%Wg"8NDK)1'&("3#M*Y4J9%25$,/($'*++1"/$$+#)8D,BQ-4A04H/P[_VxEjrCm–GTJ(kX$qH&„\9@'(""&!K9%,%4!-B'3:6*30515)(:5>Z&%($46ICI3Zu@MrRVvKATO*G?4NQYk/5A;F##3"&#$(0! &##*$OP+OS4=M6G[0CR*/9/-<,*:5,:G+AHFT67;I4SL%8kCws:dp[}Z=^j=[o'Bd$Aa5LqGc068(>PHFc]YxJv„:gr8:K+8D0;$0=,105#9L0J_Jg|h}™fo˜T\€>KZ4HW9[k,HY#?F32(/'23>"1=5?-.'1.)/@/);+MT&.7"2>*2B%"1*6G;BZ@Ng@av6Wh/IY9RgGJmNM}F[|8CO$(527M21KG<[CJ^>KSMVq[~Me}NI`==Q:/G4%    + +      '!)!$/) ( $")',,22 < '"   ! "+ !).&$3!#/) ,"*' 0)C2"HETH0=P+@C/UC,PX2OR=HX8M]E:[;;:AC"$|)%SS#*;J+%'0:@-#//*-"+E-ME3EP5?E/1@632:361B7)HT.HO9@L2AF)LL1IW)SHBU!V-)"!%)!+*&+"* +&#*(*$-3(511,   +   ! ! '7(@8BE#:%)5/DD.;I$HE.Nf9LW9QR>yc8Q€1Td?Fd9:O0DI/6`Z9W=JVA,O607/&4&.6%)D=)-!&()*ED$PT )=<3!$F0'%&+'%"%$"    +  +  +   +        + + +  +  + + 6'LN8NU?XO)8C, +''2        &9#IQ + +    +  #+*1<6,.6&;2/6B+DG#BC&@:+dm6‚‰B‚–>ŠŸ%ˆœsDE<!+*)!+&--(5#K'0WPV`Jgt’g„”ei‚HKo.Na/@N+09 (N:$+*)"&(;MN/OX31>@1>F)8C5>3UnEhyKJiHp‹YcŒM(?318F7SHH\.HN+KG(8G.+<<5,+4H.[W:-5&(3?2(04)KD'?)'31$hZ"fPK^Rv.(FJ E5£Y€€…$18hM6.7*=D-;PN\b>¯ÀNÿõG­:Rs#18.=-;(46",+8&*".'%2 ).,*D):B&IK23A73?B2_e9agVs‚D%9I77C@>X?4L3AR-IY"KT4C'>N)8G&8D$/?4:$. -4$:D/]p.\X:>)2>'0! //0G?JbDOkJYs5Xc:GaEVn@ObH?\:BP!1>$DK-IT_5i=+HK;(6P&&,)%"-"?&,:.)%%!+>(FB,7I8'6:2,390/CC,SI(Vc3Tl6OfAU[0Xg7Sd8Mf3>c;5M;4'&%:+8C&@!1 !.)*!E,BICDDCE&%*! '  $ =( 281  !""#'#"#'./)8%78(.K31'1$)9#+:;(5<.-*#3)+& &# ,.0"#)%?-"DK)=M>KOSC`N[L<4(&.;B83D6K><2RC5CGDE'QM5NmX]_BFf;3A*G:*AC$&C(9,".<;D,A&(?6':6);%%E260 (;!$*!/ !     +  +  +           +  + + +  + +   50OP=NTMc\EYy@WZ,DU&'M-1<   + + + +  %4CX*6?  +  + #-017,9''5*/8(>B 0+*!85 ?/PL)I]<^_=@J>`O/J3D4#F9 20%J8XW*2 *"(+/)"(#&$&((0++%2/- !*%%<",-18-7cT4Mc:]u[cyn^noDe{0[l->%D58M+&'.%-NiZ{:?"#%™l0’‡&,<2-?@J\;=P8H@)PN'Yb/0J &-,%FA)"66%E0\6!l>$Z2NG,‡¢ZmÈQMnBE\?K 9==A,5BD%NP4$7"&$)-/./:4*)%) %(2,9-9),615C CC!7E"9E+6&.!!)!!)&,A(3=-AL3_b0J_1/:+;E:Jb<\n3_p0V`1;A3A*EM7Ke=Sj%<;)&!,!)>0,@9,@=.KF\p54?6*ICW|=^d4L]'GO*GW2=T4S+0=%%3-( $(%        #!"! !"!#)1# + # +*;/23+6*-I.HLVR-[b2Kb;GU9HYAMULPR7NSF;ZD9LG:B>598c)IC‡:8UVDIj?[WHZh=Jl--2%0+''(3-(3+!&#)))$/46,%''!!.'* $.%03#=##1 /3A6 4K.2*,14.19 7A+ND5=Z4DJACN4CRA,A515&V6+T\1\h?AhJF:500.L+:939918,K:!OM+T^,+R;<8(QG)Q\;[eAZk?9\NCA>GS-GU:9L?H4!4[*"81$2-%%(&& !# ' !)              + +  +    *!67;9@EBFH6ETC>C=QE;P<),)$   +  +   %.+O:4%> 3.91 ';-(+! )!"*)J=EO3ZX0Lf?W_L3>F[dB]m@cz6^j8jx8;b,$!ZZHcp.G^8' +A:"91$02"%#!!)2/#.$&,(%!)$09#,?C/9BJIOKPS5US@E)$:+G\EQ*"0`M6`€3Mg(.%0J0]uYb}jBZ>…ƒ‡}’lgxpijR~=Un1=F 1B@=BI$7=,.B%3C01;88?+6D*<'3&4:*AB8?VFB]Lx‡L^o,?T!."X@(*E@4,6GP(7O(8E%-<'8"*$##/",14?)8;#Hf1S2$5)&3'(7.6E1Wq:]pRq”Gd~ChyP_OcwA^s0gi2r|7~ŒBw‘B\q(4B*RZ.&TFQpIUm;]f.CM#2C(DV/M_)[^/PS3=NTDAT5;N')9.) -'"# $   +    "#  #$%'*  +$1/0 35!/;)19;77D IA7PU6OcDUX?Gb=MRAMT;AXB>UE7H:B;085/E$!24&‡)=i\9:N[*)27#"!&'( .$5*"$%.("2,0716"8?+>L.FRGQ^CC\68e=3OKHD;G\@CVACZV/@P?@L9.J358,/A4.#,*;0?@/D*#<4$27$0#.1"24$.8 (;$%8'.1&%/!)1)%4,( ,#'/)-&./.#$(A4&A#7.1@$B6/(J$ 2#'$&+'6D)&FC+-6?@+LN4:W4:E"SK Gm@;YIEIB5O20"&2'$UC)=XI@IC37"2F+IG5NNGBGFQ4KT8P]@LY;BP1 *49 "$,%  +      +         +    +  +  " :<+9*=;04C61;748V=(/&#*"3  + +    +  +.#16  )&.,),3+2& (%(87:=DNUH@SQSJ@7Q2FE?D[UWfY_cPOcX}…I\iNeBM4ZXVdpLSu-7E-38F]9IZ1LT,LP"NM4A!#-", )$'330>%*&$,!2,$.=62<=(=5!#:*$!8O>g-4QF3:37A#6`>=XTOW;Qf*7X!L^6}©Z\rL‰ HD°cn¢w~z]…e™›Rx‰G„š-at#BL2NP7LS0BJ-*:.%|~>B`>01"9FA.K‚3S{1@OsoD·™E“Ô;d—D"2:;;?‘Æ^a˜Lnc_96<+0K70I+#,!'-1E> 6..3'1A$*-$"/4:FGEMWCG\iI]N9R<0AC:GAZ{LF\LD`@?V09N%9E+9A&29%$0*EV=>N* *"&/ #&,)3'/%.'3(.*"& ,#/'0#(''8D2CU/=P'-A'#5!"/#+'(30#1?#$)#$8%1''0'/!'/',74@WG]yI\yYSzOTrFPlOg„Mf„LcT_‚UVW_€Oh‡8ft6]i/*2)-59+@A4IHA^CL\.?G1DS:HXBXw8`v.NW4OX"43# -""0+P8_s%<:7,F9)%'/"$%  !$ '%"#'$$$(#*/*#!/'('%<7/JP5,U9.9;(6859.:A:*,9C" A1!'%#/",&+5* 6B$6L-7N8>;/@K)8E=24739..C/MB)LGAJSI-=[B;>60B63?=-?:2<.C5.ID-/C::8<>;0AI9CO?5MA8GC-E<)@5&>/&3+*5."*"!  +" + + +     +  +        + +       + + 3 06*9'9.,MG(T]8DS3=E0%>40>4(3+&"""    +     #10% .)" 1,/ +1'$00$!#%2.FT+OG.JMFCR73741YD2301A?DHL%1W<>6-VQm]\oQYa8PoEPFY]icSiDNJ(7=1;:4Q@FKASZFS^FGP-LR$>R*!)0' 5(.030B!-5,-3-JB&KGFLRP#NSTP5ZdCTO5IO#0-,<=>M5BJ.IH)+50->0064?:=+(51.C-¢V)¾£):9*+.*A>0Å”vÿÿ{y‚Z=85-238.;QVAHN3?O6TBHL$/*+9>(3>,/ '+&)$$2)#!""'()&)(1(>;5EZ:IWJ8Q?7L0)2)/92)E=4H6.K0);('6"HP(EM'I`B9N9-@;2HAKlTIhMQpP[lEQeITkQb}Lo„?G],*.!#.&$'*5/)>COm7IV,DT6FW>IbGXn:Pb:\m*KK68   0=Mk-KY .406N-8B/9#/#*(!0*)>%5H)1G+2A4;O6^o!IL#$" $#" '$)', ,  #  '& )*(+91 1= .;#69&=C*CB2K@AF=KJ8JU;>XD4J;481A(*Q*97+X*(H<+3O46O=6D88?35E4%=84.%3;59/=+#6%* %"!)*$0# . "$"+##*".1.%2$++."3+J>(JJ*5N*8.'&"-)&8.C=DOUO%JZ+@O)1O$.>-J?/9T./7!';!T6$Wd2/`>/35#8= "/30+"67'27)2 +50 / ) +/*>8 JAFa06#0$ #0/,*&-!'(!&,#1/#YHOO)0)%8/?IPF;C?5D@R\-Sh7WN#aT0@4.*?$ H/DQTOO]P>\P$2.D2TOWV8QK=44$9$ ")C;7R`HJWIL]AAL=EE12C".).9 & (1/!;B--4)C<'OT??ZASd=Q]@P^I^mBmuT]eEhi>Tf.=S3Y`HW’=`j/Wc2HV*;A4OZ?\€VPhfŽ“9vs„Œj”ƒeqpp™ty ^NvMGM<7L7ES6:O3@U05H%+<(59!!-$:2#DIIO&^c,$85)401@&¶•W½¡až':Y"*66BR¤XÉNI4F'#."&5*627IX7oX+kX4„q7{{2705)00675@&,!#*!+&+"-5 %21$42G+26-99D+0#-1;F2@%9Q8:"%(!.% ,#1)4%3B*BI'1@$.'2(*&$ !(%2$,A(,;!6B(:I,1H5-B/'G,DR(2E3AR;?[DQlFo„Ajz=XkF^xPx‘AV^$(-(4&40,H;Zg1DW/=P4RiAZi?QgCZk7Yk,AO76  + +   %-?W:D^(AN->G+.9 9G)/%"+ *:';J$8H*0A,/@:6P=U`&,")&&'%" "'!%"  ))""#$!&&""!&%%)")( "   "##''.2%>$(1#/5$36';B,8F1.F89>08C1;E99F:>9<3>+H &[0">;/A./C/+B2IG)0,+$  +% &) !%'2*).#'!%& )*"++#0.'98$@F0KH1BX41WKB@ICR8=M-:E51B)%63.+0  #"%1& 4<&:CC5FC-@8-=- =/4332?!-=(6-*&&+"#)"#*) #%!.)+2-/*.!4-/999$#>+&*%A2$HI21H:C3%2@"C#&/*):7-@I35M?3>4%85-$$+,=2%4+.-S<3Y=!3H''#1 !( 71+9$19*2<(1932.-;!** %1/#"$9/0E'+8"..&$--'1+ ). ++& ")   +           +  + +    + +  + + +   +  +# '8!=(@)E81AR2NR?4L:'35&'!2:10/LDWa#@D"oW)d}5bk,Xf"`i(cg2_^,;ID64&&"'$),@J4J&*'0 (6"X,'2'$VX076)H,*(,+ISHScBGXB?P>KM95M//@&) ,9##0*.:;"UF27?/&@-&0@*7?46DQcO\lKNlLB2@S9/a|FJd:@D(4?LW4=OS9+ IF5MS3^n>}—8aiPqvPjwoG…WTX>U‡H_†6;D#3!/7*VgŠR¤z\ba±³,¯¬'ZqFQvZ¥Ÿ<¢’'M>&."96$PLS’À]kŒFkƒQ`^:t{$ˆu'…… rP à™'pE*Nm9957""$,)#$("(## "($&0/<4:Z$?N/61<&+?(:C0WW5Uk8ux,mp.}u&Yd#AP(>H5=:?'@P,?T(5H(8L"+$'!! -!%5&?N(KT?H1>#/)    !(!*$,8"4A)(;$,*&*-(9,;I-Ym1Sh:KhENtMeItDJhP^‚LWn(>I$("%%0!6AKz—?tƒ6\d3L_AVh@]lEfzCg}5]l+RYB>/- 02 /.  %,%4D6;K*;N09C(9D)K_"LQ-4.8)5.;N/FO.H\)>D0,1@04>73:0%=/?%F-046;'6;**--;.#0!$+"# !#! #$*"!'#)-!,&&)+10%H?.CS6AW=1KK=A8+J7;=:AD;5G.1B58@+/A.)6)(12*%<11H%'A7(74"42,/!)&&*$5'!6''$',&' ,#"'$.#'&"+.$317C*4C.9A0A)@%6IEG.-E8,8(#7+4& 2;52<,%B04.-#5'"**(+#B(KM:W@28*6;-""% E5 =X*+B((0&M0&1R*'<%8!%$ ( ++(+1 *&# )#($"$ $         +  +    +   +-$'- +(+ +!*  +  +  +     + (&-.1(5859H=>B@;@,;A 4>)E<)^Q-_mDPhA6TD6T`>[M7\O^[Q\|T@VNdsHh}3Yo &%%)$*!3069,+ $<$!#.'".,)@).H=H\IV2HL,bXA^€Sr‰rW…f,67)7A./C5.F6 5)'# <8CDC8(5A:;F?,A)(,##,Of.bw4Nh-E\ITg::G.gR&‘2gd&Wb5m%m`6]YDWcSNZkSeHI_]t€PqkF’A‹ŠJHLE@T-=B @H-%2M4=J%*?LZ‰^Åc+60FWB_mH|P|“PpF[}43D-6D)MT$27E W].\f:`z:Sp9Wo9J_FMkYh‡=L\>H]IQh3=I"/?%,66AF)SZCr‹[_‡If?]u;\mCXsNjS”JXq:Pm2P`7H%JV!7>'*&'.?+4E7Yf1\_*V`0Vp:O^%1A =G 5=,)6- 7:/I:JV/;K:EW(9B&?D;9L75O@.@.:7#$1*/*">80.6-5/+6.321&@!$4$("'--5'6;05>&+;&'-#)-!,3"1$',$!++!"#"%'*&*(,/-(7/3+$!$$*3#14)0=.0' " ,! 6.$4'"+'+"%*-70951;./5F)5&!C4%2-%26@9&+  ! '%(5)7. 0%/0.<EGBB > 1 6033$)  +  +     +   + " =-034bW/de1]hCYob^nQSlE=-09-3?6->47MY`vFLPGY`_gwPVr*41$7@ .2'@ '#+(*; =<+HP3Hd=CWEKfT@M\FP]WT,eaPi[HZ„LŽhvŒmhylk€ax„\It@XE;{S]ƒ8L„6\xE{•6Qo/;/\K&p{@f=l€GBhI9_J2H;wp(el5…„W„ªmŒ½v—¾r–½FPi+FB-O\AO[LXYC_a:ee.efAzp;ƒ•T‡—w©¢kfnYmxg5VZ&1?9%)5*B=0ZXDo‚Lm}^n{pQx]eyXenW7_@3<(0A *3#*3),9#(3+'14786/EE:2\0@@;)!#0+@IDG1OjC=^8AM0ciAtŸ.SpObpw\yK®¶D©¶Oƒ¡N‹ŠO}qMOsB^o>z—>^rvZˆc”¦Œb|tLb/IE7Tb8O[2?M"7A)`LJV9“‡GCX;B+'7$""-4/:B,)40<3@dJhjF_a‹ÂX¶óoK`oUl¬k¬vNiV>O82A+DP8J_<=T" ,(&"! +,%0"'5&)<%BO'Yf-Yq2Gd=[tF~D\hLT~8e|9\hL\rDL_2Ga?F\9?G'8L%NT+cq9}}=s}K\tK8M@2QBd~Gz’E—T˜a… MGa@=R>C_(2@'3D,)/  14&,=%2B;FfCWt>[rCXnBiy-NW0L5/F5›F(—C.“D)šD)’E*“F+žE,›C, F*¦J-¢H0™H/”F/œ=%A$>&q<g0 X.G+6%.'! " +  + + + "#$!(' #%# '&/226(*4&&-)$3(+)).$% 57 -!  " #  36/39#&5"(30"$'%'/#5().!7*(;+/)&60"67!0C+-%* $%13%%9!#1&3' ('+''%#&,(-"+.(1>'#?+.!%,'&*(27/8"!2"$!'!("# 4AG2.8-)4+#:/B!jZ;jsVVvTMoXCBOIKX9N=#%+/+#+REJNpBCTAjN^Ap^(@'$1-$=:06>*)21)/" 2,54 ;O--N=/B;6I.2ND&7,+32VVASoK@GAY]^n|jryynhhxlZpb^kRFxFE{b.6T>OQZXA[xpuuQkl0`^E`obk{f>]/JD.;1`P*WZQˆ}\QŒn[x6R~/KEEwWŠMGQ:\a=LtPedQq~WynY„‘_™cnst…—rf‡]pQIUYA=".8"(%-//9!,'8;/FM0.670?1*3;2~ƒM¿Àj|ŠS†jdpQ‰dAPuU8NUH\rP3M<83+II.h€E2Q=GZcNe306+,8&+!( /:$(0F8$#<3+/<%,I+e&9^*I/K<;:F0D4/;+:?,=J55A&WY.LM+=6B$CS%EG/1F=;]BBaAH`EGgEfx5@M'+/$%$189R=N]3H\3ˆKEEKMDŽJC„KE‰IBMCJF”CDKH›IHšOL›SLŸNEœXGŸNKšPIœMA E8H:’E3‡C+n;,Y8$N1@/1*&%&$$!    +    #!!('"!" #&"$'$'% )%'(!-//"364!+$'  #'"'"* "#" "!".).4(/7(+3(-8!/60618/2$/-%50$#)# $!"'"!%!8#A&$ % %*/$("*1#1%  # /"-6$)3,&0*($"!!&"&"!(;)D<>K$BI72D)F=''M6,6"=1$<':)&C$),&'!$&"%).2)(%7%+ ) "!      !%   +  3&-+*+ ;+GA*2E19'  %  +  + +   -1*-2$12M7IHXOKP%!;%)     <-&.<*#1-*,#+7+-"CHDKb^MX^WZJci9]l8irG^l$/2/8@EUhVx“MH`Kp@;bˆT!`^1L/2/fX+CD9…aKuœsVvZUPGm|.@M,YQ5uŠQd˜9K`J]qKlFer^hŠah|qƒjpdpyFT\GQLGIDLK2FA1HE<:&UOGG>8WRA_dMj^H"7&/$"*%13,8'-; )8$-;%0"'+4"*3A;+4T5)2%55*+B*=G'Ub.GmG'C8(24kkPÎA[Š;s|\‹›wy­ˆ¬­‚ÖÿãS‡¸®€¢×|¢™a¥£`r™rj˜¡ct©n‹—B{’=…ŠYS`L3?M/0%08(56707B0<,66BDH7DP&GS+¥ r >C,fb$@K)?961(+),,5.,,036E0/0&53%GH-EU)SG-EF2lg4DM25+'%+*DC;:$.?/4@(:T=et/ƒ5¥Y•³Y†¬LršWs˜Rf}Dl†Ic‰W~–R{’[tœNk‹K_zEƒ‡R`~S|’Z†¦Kr–71H%$8"(')&. '$!+$?F6JY1AV-%2(('/%HP:@!, '"*%!  $.AL-@K-@J/>J*BP)EM0DK,EO*BS,AW/BU2GT0GV1IZ2C\/JZ-MZ1Ef3Bd5@a4B^6Dg5Cb69^44^3.J/*2)),'$$!     +#!)&$"!   (&%('(&'+,#/ +4/#(%  "*)%0#.$'$, *#&*#&.&- ,/*&*4#%4#31"5<'=#*2$0-+50&#!$  (',:(!9'! !$!!-$   ")*'#  &!+ $/    #7-/5=5&8640'D>89C!N:@D63>%     %   + +8 3  $D/NQ;W7FDA?-   +  + +    >#$JB*DT-GU=OVDSYJSaA-D ).'   +   #%(;.$5))($,)*1**:&,493-P9KQD=EU6QO,NP0AC`(!:(32R61ABA*9"?8&2<#10!\[.0@4  S83lmZa}aDj:%8!-49+86(7)D>8I!$2<'=k;Wa_uR>a;MbN_qff|i^XN{AQR;KQF5X2.; )5+076=LZlsBmn5Msd*2%9+tKsƒ9W[<:gRicdnxRj’GV\[jF3N@EI^P‘iPpAhzN|ycxg~†nztjsYkkSXLBH?52<9%2#'GH?O**:)-4"'0)9=#&0$@)5/>+gRC–²nŸ­V‡ŸVu•k]m‚±†¡¯Æ¼ÅP—Ÿ‘•¦›•¶¦†ÐŸŠWc}MRhTUcw_‚e€ fušYJa;LJ)@@&B@K7"?C 87'/9'KL2–}.°¦L…Úk»™e©¥?òµ9l€(Z|9`‡/Og ;H$,/6>"/?&&--N6>B(,7,A7.o_0VY0K]CVZ*J=K?',# 16 , ".&-=')53G_O>XSZ‚`|£dc}Ku‹M~—Q{˜I{ŒOk…OmOpOg„U†œPŸ¤SÉß^ÁßQ¸Üd›Í]€ŽF€’"]W"*18DE.;-5TU$ho4E^0?M%&0*-RP_]*8V,5,7*)4%,!+  #  #*4AQoSWoSVrAXzGYq/7*>QB[}C\i*S[DK8@26,:K9BQ@J]L, /$.%-&/)3'2-4,4);'5,:,:-7)6,=1>-D/D-D$/B%0E&/D4; 5H 4H#4<'3.!',""'$')%    ($.!*!)   ! ##"'((,'4,&#'(- +$ *,061&D"*-+34*9/132'<-3*. $/ &, +6 15*? 5."& %/ 0)+"(/$-',+/-9"9-1)  ""% #'#  +  !   5$+3&   !'1-0)"6A&(=0-.*.4+1"& C%?L?L+I=+;W@A; & $ $$ " +  +  (;-)   '&+!!,;'B-.#  #%1$ ;<0D<4?&/-!D9      2 +=- +F8>H 7A1)(  )2-H8 DA0 <@JB%LHMKG?SE=G@H4  + +  ++8,$( # '%5&'8($2*! (2-.(,?250,".2XW>.I(J?'9J-*;$0A4CI;.#1B!(Z4A$(4-#=,!+ &45:!bb1t”)njEM)DQE=ED)@12@D[rI;LQ|^ESt>7T@JY:2Q-++<80E%9BC_`_\ƒPBV&|U#®µT¢²u/‹O%1@MGM`pklknŽG~‘gz{=as/npSYmJ`SSpkhq†znvq£c­²cŠ“]BQFIE97A)'/-2324A9<;$=J*5A81D2HM1PZDFdD;H$/ & &+0&)/!,"(A:81KP42I.+;*"0< ,:+>; !05.`JU‰“w{œxpad¢N[q]Us‹[‘²{†j‹b€…ˆ„„Öúyv·O>T?LX<[lNZoRpwcb˜MNrB?nAN|;S‚Dp-ai$:@&žv?¯´käÛ{q•YYu]¸“•Éÿ|Â8Cb?GbIOo3=[0'G>A*6?!-+!6E/CI$23bE2_L4BF9JQ1@B4PF$73"99+&-19 *3-";I6_q3vŠFs“Xy¢NŒ¤S‹¨[Šª_†¯aްQ„¦Wu•M^€L|ži´~Ãü‹ÏÿƒªÙygn}£^޲[Â2†!gs(p€+dl#Vc-k{Dm€Nu–Lf{L]~_hŠWm„S„žN”žY–n‘¶fu™ft¡rr¤qx¨qx‘d[_7_hU~fQfXEWF)GIK,9I44B;KK;=S,-=",   #" #"5,19BLR7QG9Qd6:K"6 NDX[(Ta.!@ ""34+;,.$"!'$  9(5"5-9'?=5MX5=F$2G4%:!(2=I*1' J>&3*""4):5Ef/KU2GD-E:1>+$=$69C::HN.>RSIG98=B5=G>FVEORH]*=BYSxw‡ƒt`Cyg:gT}AY—TkL-P*"8&0".((#)):5)2<;&2*)45'O8;>73HC&G:(43%57*\>J<?4JB&M^+-=3/*41_uC{šQX~JFcR_‡g•ªi¢Ínµp|§i{©ZlIWyGBkYTqi{¦Š”·…u¡doL^}_‚›YNo[W€J\„Iy”R‰”B~‰?Qo>:H(@N0}‹>Sm5,C8&&#'9$-#%5@(2= " %-/DR8Wl:XbT`zLZzJIs`Qt[QrJ?\_a[›aˆª^„µj¯hj—hdŠJPugqšivœRBdA4@2.8;/AME]EGZ0HQ.TZ(DE5LXDHhJSmQLiKcyA_fCfr6kn.QW,;G8E]*5K+9J48H:AM:EUCH^6M^=G]8M_22C<2FI!    + +      +  + + ' +,)-,54.-")'&%-(&!* )"$) $ $$$ %#  "#"#"#!"&#! "$##*4%;1'0& '$+!%% !$(&*!"2 +/+91<((@2+2(,7")2-+2$*509.<.8*= #3)"/!-%" #&%&'&/#"0$("&0!+ +*$#  "&$&0-&      +     +&#% ,(.6'9:(/E3*7(& + &%&,#$  !' $$ " +/3, 6@)57%8 -&+ ",$ ,#3/!#.  +   + E:SR*_MDOIL62D>52C6+#F4DE 9:-2   + +'')22+,7#A> -E6->J?6E3+7#$ * =\V2XcG`cIEaA?Y(=J!MP`c6bkKKoUIU>';$:* !&!,  +@-&*=&.L^CMV05G.#=$(01/$#   '/ A.*0#5+ $"(""/'.'.?@#8J&BB2?S/DS2NM"eY,ib!6I#.kW[@>9JJN=i471C=a^;X-4F"9>;LgN7S88F*cUdFkP~zN\zj^baaƒuŒ€q”@-GK/:uniWoVtv@3::?8 1"70%BN,M^3GQ*/5'23(3=69W8!90 !)-$-',+;  !=F"SX(^@3>a-JH!'4$*-(>60C>%SR.=8&sL)‘™b™¾Ñøt§ÏerœjMg’m—ÿ·ÜT|œ`p¡\RV}I]`H_cW]vmi¥YŸq[hI”¸Bvx>pwC`iAjd/øÈ/vv*\j'a]-9AXJe€:zƒ.qƒRˆ®kжhl“Zm‘V`€N_z83Q++C-6LEm]m”sYƒRkŽCB_E`„N†Ÿ=z‹FzˆO`†[‰«W}•Dl.P\$/G6KlOWw+8F#-&#,+'+ +/D     $/E5.A51GA@YI1KB(=@*<<7K5.COJ`X\}^\{ejeošSc|JTyH^sN[|SMuGHX-GR)H\-6:>=HPXpE_oAWu@s4Sa9OgBD\HKe\b~enbe‚Ye}>]}7n5Ur1Wc5dt2wo2J]7QfX:AR50:;"   +         " )),0143#,3",( .' .(#%'%( ! %%$ & '$" !'$'"% "'!&##! !%#"(!."'"'%#+(7-E$82#4(&,#4!- )$!'%"$$'#$ .&-&"0($/,58:!@> 9H$+D(3=/?"%>' 4&,#*#!$%'"(#++&*(!$ /% %1*$ %" % )      +       )&-0 : $()'4) .&-  ! 2* .@'3#,'-" +! 1.036F7D,4=09?/AF0/A4)%4SJ#KY-E8-4 +$   " "/+$8993G@DH6+@78C?-$G/#>S/%@6??04I/:$  5B1 >>6<$/5"3("&-3 ,:=<:<5;/8<1B$, +$ 5GH?B]PUSI]iQXfIZe;\l>]_M_mV8g[!B>/76%+#! $$3.<*(!!>;92/J@<=JG=O23 76! *  + 0&$5'($'&)!(*/%,3367FWP_[e~hCk3>M/4J'4-E-FS83TH>D"39,8E:9Y$5:'PK75D80-)4DLK:kyai‡bhfF“—\Œ™XmllDb#4<$GXJ3:a]zgHu07D1./ <>-@@72=B2A2+1**+=&.@0('"-2X1L= 9A*"#?1'DL;+T/>I.¬†<€¯$˜}+g3?Z4I]1\O,|yVy™pWFb–†¨–ÂsŸjh„BBGpS]¢Q…XeZ`lkLlCl|O^mPNmE:V_QMKfoLoŽ}~´Uv•SoˆG[sn§ÇÛl¾Wo‡DhlJ{š(‚z=suu«È}±µ€¡zTy`*@/3;!)*PC26,.;;DKb`.LP81.Sk8ON7dVPŠTu\YyyH]h%P>+/%F2&E@(58$8G!)/(0:'9D*O^,L_-Jc+MjHg•L¥ÊU¨¿i‹²UTrM…œL„›C˜4BR+>#40?PVXqL8SBjBu0^vS…¦\¨ËZy¡JXu]•¹hš¶X|œH=\(#1$"3:0S:N`!RZ+2,6"(%0 ' % '!#*7PL;F.<)$++.,&(/#'1$/=)6@6QjCg„GO]PGl\o]w˜JsTtŒEg~Bk|6F\1I^9R`-4:2ENGYqVe‡DNb[mRm‘>lƒIxˆDexT\xhi^l‰XkŠJ˜Io‡Dc‡D{‘Bf‡Hc~93E?DZAL\0:C2'6,)/&'+00"&$( !''$!%)%,4157:-B"5:"9= 3D(+D7+;6=9"'H%&;2(1"$7$.!*#+#-%* 1"/ -*)$4#,$'#-"( &-,)3$76 ,+) +$$#  " *..*$- &  $ ! """##"%&'&#(!&!! '!$%#,"  '4%36:856$*22%)4-*(66!3')**)*7-6B1E/DC59X38N6/I96775?77E$$:)+ $5:B=> !/,*! +',(+0-33:-.&) %&$-%#$&$(./"$" .) 6 L4IS+3B68@5=K+';&%!3)49$-@$9A28E+'51+0%)*,C"BQ;L5;C8%LC=J_7PeL>TQN_OBD1@/+1/5>8"3/(*AO(UT1rk@nf>TY'N_2`<.W^!9jADO-4H2:LG,:?PLeffdIvw•—‹j€VnoRz%VkBug"r˜GSU>PQ0>K8B-;>-99'/7#//!6I5>"6$#!1!kE °z9Äê>BS$J5‹r”r"Zc&24&[H.~†~‡pv·p`rJpt0Ug6dsFy_Q^_VPC–’o‰§†«kX€WXx9\gNSiHHVUZvQ`^C—M…„Rc@[x9nGDiM^uNDaWGaTVaNb‡Cm}‹p~TÉ›L¸ºGÉÝW±œc…´_Df‚KNk>UfV\Bbj#WO IGA5(Š‚BÕÉ5]!Š€9¯®L¤©#—y$&4!",$"/-GX2Fb,4E3:=A78+1.1')% !&#/5> P\<`ˆ5Ff0Kb.3#&04$,*2$-"+#61?ZKXuKTl:NZ_c„bDcNHtbu—Un‡InŽ9Qk1Mi*?&-<&(7%.070:!'84305??$;OA*D,-<3.0(*5*36-.@-(1!-*%>< !A)!$:,3:":)6-8*4'#)!%+3.8.5:4A?K!*; 37"(* "& -" +E::H-9CI3G=/='8>,490+(/9-9*#3%'2"462.D'50". )0!+1 ;E4:N0K>-EI6;H8'==EBD2!+>.3<3:D2/a'#"7,)D"'0;O0…,"]9!+#-8%'/0 /18#@D&.)O=TY1f[E…v]k~WfyPNYOm}:]lM^jBXJ6:Y*ma*HR.FO1MQ:T^H]ddˆƒo„¤lt^u{ppqFŽ}Y“j¨¶OŸ=.?*9O%49&&1)6*>.#CA->/#"0,#‰~±«,–½Y•†ŽÀ—UY!c¢>‚­r Òt„¢Gp"fa6€”he—Rƒˆ^vv?†•O¡›<’—K§ªW¬È;¸»>˜­p¾ÿnYˆmOwHF`Qd{Lm|?MO6«¨N‚Ì]]„ur˜cgzG]sO7SNNPJ-4= CH/ko2`x2:R5*<2>N5#6)1#2?,-@?VdT_{C"D2(10DZKZmSDfE!E#*!(&5,8P>LiLZwHQc>@W5?R=>X\@bZZ|,"0'#"7D1F],GY=H![e,sy%no(J^&Q\*Jk CR"'+-*/.68E:M#[k6m‡B`u=.K7FaB,GS5C7-DTMn__‚N\zD[z/I_>>WHe…Er†CMiNVtWNlQIfSY‚\\pEKcT\{I[zQ\|O\yWW~a[‡Lau18JQQƒd|šPb|D[v62@6>RFZo27B.*8;!7B+CD!!"  +  + +    + " "% +#$ "#$' (%##)%' #)((&$$$#'$&')&+$*")%0 ,$'+(( ## " )-"**(*,,*2+. 8/"=6!F,M+ 8. :#6)5%6%+&%"##"#!$ /"027>-A$-8$05!/4 )7))4!'8!'/ 0 ('/#!"!%,' ),/+3'3&+*1--7-6!/*/./-.19("+")1-&1!2), "/2(/<*6(0/- 2 #"!(&*! %$.%-0!+1*(3)(2#-*%6 -!%,(%"  0 ?#   ")#%.(&#-9&->,/;%+<'*93(8.-4"2;!1;!4<6D/-G-!3$+5+/76+:4<4$*U(.+#'%0(&-7)787H/="52,,5.3!0;$4.#-'$,"!**5#==E?-E+'91-1,=/13?3E8'7C/8;+0 +*;'7<72H2;-$3&/8(+2.&+'%1-!("#*%'% 2&04@0@@)OD!=K!D<$6K0/4,*@;(56115'&=85)933718>27H==K:,'!",4*-+)@8,L;@*"(-05/;-4?04U1":'35/860=6'4Q,)A.$& % +2'6>')?3+/"9<2,3')L+(! ! +&%$Q?!Ht:($'4-A;Jއ8vžXr$C`-&3*/!)2)$, 7*FP5mn@x~PMŠnm^V‹`=l@WrHIYWciSYoBJW?htPz{A\l7\f5IcB[VAw…h{w‘µfš]Iym[j;lnv{‹£Ëok1R`4-$#'8/ G0$]B$=7I2Ô³j˜Ê[œofys_¢o?C9EVV~qc´‚sƒb_{Ra‚Gj…a_qJd{`²±l”®h‰ºn‹«hb‰zTv’¾Ã¤Ÿ¹ŒÉðŠs–J^wHYu?[oZl–dWkEwŽw]Š_Œ™OEbW8JR7hR0H,:FCqpa«®G±Ðe¡³R¨¸C³Øv¤„ÇÒ”†·s}•|‰šƒ_‚CAgEIdB\[59=:9B:c\>UgEQjHd{f¨‰Jòdžo_JH1›A>S/?5)I3'^F8KQD8B-8$6HEEb5%&:C!$5>@Y=-*#$1/;/;S]1]qEb…<4A5FA=RY-?W+!:#") &*&,83!/-'% # !,+"$/'5!@$/E-@:E1292*:;9E=2<09B0EM)/B"*($(/?24F-6<.-D+*,'2,0.31;-*/-?%: #$)5(#"!!09'*.&0:)2%,=!D5 ,*$%B0#.Z83$)# 4(%8=7 ((+;-%#+"8*#E9";*(#+GG)F[O+ "%&$cy…~SH>JQTXMO]4Q^Oa__f”Vˆ~S†QZ}HEj\UNXw‰ƒl‰f(29'.J;++WDD›œx®¯deˆE,>'")&"&%6%'A:"`83q‹5^{CXG®F¢^*UW3GYL{“]gdL•LnLduVLhJ˜o@ˆª†{V{jEqiUdM†‡PĨo¯vtœ”‚£^£¾J¦¶Cc{IvŠ^sˆGbvE†T‹¬dPe2D^3JS-À°#º—4äïdÜÿˆ²Öˆ›Ø€‰µ~”·rz¢feŠ|Ž…{Îáw†¦upŽMMI-LQ:<]>=T,.C/DM>:RB-D@/6F‘•Ì₇Gw6 ”km -'I8.ES/ED2Pj815.9I7BF%9@#5D&ZT(-409-8(-5+)+"/!"/$*""%'+ ,#'7\_2™C~PhˆGz•EˆŸ;Œš*Li![[-mu,hl(}z-[i3[h+CN&7G)=M3Xk4E\59Y9*' &*!"%$449S)+)/":K0BO2?Q1GcGavL6Zk?QbOZ|CNo9LV&':,?@'($&&     +  ! ( #*%*#'#""!!%'#"&)*## !'&! "!  "%$&0%++-'#*'"($$ #&!%&"*')'-/0,&10#73%e/$^9#P=(M0'>-$8$0(-$#()!%!"   "!',*,.03$-0!30$55)+4../!,1$+.&1 7-",5"-6&57$0: ,8$(9 *1$5-7408/446!552;!28*25&45$49 76#)6#.0,5=<$4>'09%>4$9;">2#2="?=*73!91-C00*-8)979F$2A,#0'&''"#$3 -3/343**( ")!0/;)39130() /# +(!+&#'#!&%# *&3*&'&"#/0$+"#')!#'%()&*& '& ))* "2)" )%0%2D*"2'"-'2"6&&'**04:/@3C'8I)"5"%0+("! 6*&=-&>I@:J@';/.)#-!.'"'&';*8(11,*5'07-3&$"'=6+NN JZ!+L',6!I6/>U5OW5W_.KU dc)^f5‰6ut)qp.^\0AQ0Ja"6E(4H8ZnDiu.Hb9k€Anƒ>Mg8SxC=^QNlVP{jYŽq„ÂoœÃ?au"+4A :C$'#%") ':+GV'*%3E22M//H2EaKaƒGar?HiHQuURe@MiG[8Kf1HG29E:`i;]y:tz1Ud&4<-5B($)#+'  +  +  +  +"$ .+(%%#!&%'%&&$(%  %"%#%  ! "(%*"&!% &$"!$$&"($($((*+-/+%=4#J4#^1$T@ W60C2"=-$:&*')"(##$##+,*-+ '%')*$ +$!-'"2-.*,(#'"'*#,+(,0.5$"1'*'),732;!,9!(1!&0#)0 1-#,/#20(2',3+3!24"00,247"4=)5>);268.8#31$4*/3$-0*7")4&32"/8+8%,4130)/1$-)50;:/=,20-!1, 5462)4-3:4,B%,0)*1$/2'3(+',%$" %'*$',''.0+4+0!+$*,.56.!)1(%$!/)&,2&3"./%:;:94?%E!-016*4AD#6K(#8.9"*:/8"=C2G#.=%,.2+9*(9,04 *?!8$$1' &D64CB7?;6E))?$:"*+&$  #(#--#@C/:@8:$:N6R(3H4,GBAW800.<"*;8)*+#3+301+53!0)  #'' '&&2&'"+,0"")2  4,') + /)80*$-)%+$76/4('1',:'! %$./AD/:P+!3-).)'13N2.=N&DG2aQ/f§qŒŠjt\ަS‡¦8{s/82HEia3Ž‘”ÅĉU„eERm08<4HJPw3;!00QI}Sj>ruf®Èz}¦x—R©Êk°°oƒur{´ry†‘œžr}UdˆVXzomhq„’Xvjf‹fQŒ\LbOknIr˜b¯•K€’.hr4|ˆMzOqm~¨r„©hœ©^†œkM‡oXp`F`Fos77Mhp75G.IT)+;%3&+&!$ 0)(brL_„QNsX~¤fzTYuea‡^[hCnŒE}‘=v—r™µf“—6Xb;|†BÆÌIÍîX¯ÉF©Y¾ÖMœÄD€¤9jr9EO)2J 4G/LfE|‰6KnE}šOx’AWq6D[7=V5B\?KjCE`WEkqw¥Xv## (, 1>:D*-;!'" %,)@Y':?!.8,,$1KHKkIM`97R43LLG[@F`@NhSv›j‹ÆlŽÀ]ƒ›Yn€JUiCJYLU{Hm=etP):N.5+/&+2$8A-:E8)B)0#"'&"7+ AAFM0:B45F+6)(A9&)5 %'1%%*:#4B/*3)@5@J#0A#&3*'.#&% ) 5=2; +=%#3$&$%% # 5& 1/2;#16(-4)%&!#*!)#%.%7 11#(#-,76HB%bO/GM@H^RhnUXs4QV+LO44G$WK.B/;%,>*,4(R?*\v[“t®¬x‰¢_™7W€ll‰Ÿg´ÃZ¡ÄI}¬*) '%!'&' -$'$+3uR/Œ‚HœzeŠtZƒzTmf…±r•Ï\™É2x¹H³âY‡§V‰©¬´`‰·5kg"KW")$13:/M<ab,{z=—¬V‘­’ ²t’¤}¬±”¤½…²¦f¼_g~dv„jŠc~Ju‚KmwLŒŠQro9iwKµ<Õó6g@v”M†§|ÞòvËS…©_`†dMmV{—\¯i‘¸€•³p™µD–§JœŽ;ÿÿX‡™1|…1do>q†r–®¦»²³Æ©ƒÒ_‚UDâ­eþ•´°»ÿÝuž¯WhrP@YI$65;0xjV+6N7I•`|‹fzV=V!/5,Lf#`p#4F)*/"&/+%*,-"%"&" B9-0./"<@&LH#=A-XV'CZ+N`5cw JN("4 $0:SjNxŠV}Xb‚Q€™>l„:ez4Ph4Mi29Q4/@D0Q\]ƒ;NS(1.'%#+$+.,&5H*:M%6> '/$4$4.!9?1H/(5$%51,F:9I8ChKIocMrqU‡niŸbm@DU34I?GXNRyJbˆQ™P ¸Q…•Fy{Q(1E '&"&## +  +  $ $  $'" $#  #,.#*.**0%+,+/'))/+/"(0(1%*($'('(#3%<-Z, T7G='/3)*&!'-.(,!9/(+ *$ #!#)/ -&#  $%+&***(.$,+*,)" +#.'-+($(%) -"% !(.$ +&$/&.')%'(*%**-%!0(2/--3/5* *)+$3%4(3)"1)9- =,;.;2333$',&(+&1573$0/0-)/&'!,#+*.+,%2/&4-#506,.05'6':,1,/(3*+/+#.,+*;*"4.:-<62886!14&5=)<9"1;/:88-.E)25&45+7G&-F&8: &5/(12'7>*8I--C-302*C&341K>:(9B /P .8$#@1$11:-4?-+<,;229-!9('9529:.8-5E*4B&,A0(?9+88#2)*/%9=9;K/:F(5E5,)2$!(6!3(+)'1<&8>$:?:/<.#-$    ' 4,$4+(*%#+$0("!%8.JETR#LZ-9E,)5"//" '.6$&,$=$ .,9%2$B(+I0DI?O{@2L<=XL;b\YC=9P1@F 5<8P^;)G&>5(>H!RH-XwQ‚r„‰‹`zwsŒueUNZIšnu• –”§j…z8S%0#% &)&,W@ywFw°`NT[M]GR„H21.78[K;d|gfdUCr’m{pWtgx†|sŒynf³ÄWe~|p'€„9…ŽD“r„¸™S†–v€¯o¤™k‹®Š›q’”¶´wœ¢]‹©_ve\‰KJ\Ng…Uq°r¶h»â_¤×yFs€Oe^°PoxJxœŠ•«sv–S…s?§¥C¢Ïo¢Ä‚_¥wY…tŸ¬„ Ós²¼fëÿüÿ{bœ_…ŽXˆ¢i~£‚m–yž¥Ÿhq`J}rz³ÿù“Ñè©ÿÿΙÕt‘—F+I%.-2M&*8@0:-4'.6<7?52B&*1&Rc0.;02}‘,;C-4H2 0(&396SFbm'*2,&(4DTj`:O! . &&% $!IN.¬$b^>8-+A:AŠ=byQeƒ`SrYo›SWPo’Ql2{{7oq6ei[xŠW^qKiyXµÅu´Ùs±mdh‚œT[qBi|[u—kn¡eŸÈ[´Í;†H…¢HtƒaM?WN>\^e”Can2N^:@]BRo]l‡}Ž±ŠªÁ‰ÝÆu³¼K~}OxpF\]R]zCPh=Ur;Ri4X`.5C+-/*&#,(  ( +%#$ +  +!"!!%)-' .2$"""  ! "'&$$"*%'&*)-/-0,7!.3826;3<&4>&-;(3!/3+4+-(.()"*#(E&J/=@/:.,4""/!"+((,-)%%-"!#(4!7'B-+0($(-#&% +'+*),%+ ,&-**&*+1)/-*)),*'3(&# !)!#$&&*#*&*'((+%)%'#,%'/ +) 0)...)7(2..-#4*4-1)*'!0)#+(%+'."'&&#$%,%%-,$1%0/!/( 0'/,-+/*6%2,0,1),%1&$:.-- +"-5%('*#5&1-0(5(7-66+;#-1/4)5 01!61#22%,<>=)3B+:423 2->6'1E @7!8D7;7D0/D7=<'BN"&18)/75):*2%  /$7B A=BN!5?8/.31*,;9AD"ELJHf|C`;y,I\A™µAb}[jˆLs–IUnHiƒFPlEVuLˆ›Lz¤aÉðS°ÔN™œG„~J‚–Yo tWw_@QGTtPg‹Qp1OhPk†LazQ_s{®l™Ð\³eg¡Lp–Ly›Wz—ay¤d„¡DUl0&&%&*!'$-$*()!%&#()2>+,6"&*+ ')+ &%  -'&>5:O/8L36IA;bREi@:TAWdDk}Umo`}‹]‡‘]…Žrir‚YixLDWF8TLQhCUpAQh5Rh2HY-\6&U5#-;" -) + "W B)*% .+ )%#)#-&-,,"&!/&+%'*-(-'(%&$(+'0*(--././-./3,0,462%892>$5;'5>'08%.6$/920//&/"( # .>-4;*:#'2, '$% !#&$)!-*!)#,'- *&0#;(A-\3RD'66.56!(6!&'*)2+.1)2!102//.,44-(2$0-#0,!*+2,+,-*$))&*'*+,++*%(.%/)/#.&,,#))3'-/!((!,'-) .(!-%/%".)+&2%0,/-0*4-/(!-#0$&#$0%#4)".&5(,%3(3(<(#5,$6+/(*)*'6)%+,0$1-.'(),"..8)5'5*7(!53#3->-41263/ &1/33-!40(7:#6:#B4D6!6M(69#:E)CD(;S,AE-;H&4M*2G62>(><4B *A 2<+;8)6E"9J"3E5?!(3 -))%*".9$L&6+,E@:;F UQ*J+>+6RAR06Q60J?@G(-;F:?N?PCQ&%N(I6()B%1#.2()1$6#87%/>*672+9=*/+%7&"+$.(.2+28%2@,)2*&2"%!   K3HT;N->P5CI:?F1NR0?S4 =1,("0&),0,),6-(6(08&&040#?>20=)$&0'-47$=M#B)"$2%) 2.F+)ZR#v„Co C33KG8B=#5GI8*.&.#+$6A06C&/.&.9(+ -*)*U;mDd'ZL,1JJXLp{Dyy]f + + & vL †šL©§_¶±v¯Ìz¥¿.‘§eqªz|On;}¯oRt[v^g¾Yc…:‚¹ch“upŠ€–²²”¤º}ŽºSv•QgzbVj^KilzbH‡G¨¿B¡Ähx’ˆ_—{f|niŽ]f‡b‹ vœž5§±0¥½\Uwiƒ™wTkl0GY-K;#-!1FBM–h‘£‡Íyy£Wh‘JRdn®«Œ¿ÁoÉúŠgBÿÿUÂÌp¯Å‚ÿÿ¸Òò_Œ«€2Tm7UpSrL/U.AJQKi|¼cÿõÝþ¸š½‹Z}Œ5XY@I>2D-58PX&@O'% %&;4+5 '2,<@)*//J806%4>".6 (Mt‚†þØ£µTlƒ)~jg­Ã Á‡|”Q)- $3!+@&8(!!."202=5B€ž5`s0,DM+GY(FM*A3bqUkxUUtJ|P­B¦¼TÃîa©h¥‚·Õq¦Ì]°ÑMjzJ;RD@T.%5(-8;HmJpŽ1;U>_xEiy<`ƒKtZFpSJjNKgKT~^j•[s—`Š›e}¤Yu•+GP..$'.89C9F&Xj!BQ BK#0*!.)4$2A*%0CVLI@>/-$%-+8%# &/C&.=%0>+6M;@N8Vc>ZwWt˜Xs†V[nXDQX0@T;P\HZNFS;*=54A=8YFXrGl{@amBgx?M,.I./,.8 +  B ?!""%& 4 //(*)(/&1++/!*( *+3((.)+#,'!.(2*0(3+1+,0/-+/.1 ,0&+/%- -)224779%7:$0=(33';2#B3?5%14#"1$) $$*-.-7)1$$+$$(&&('###&"/#-$.+3--/%, $),-+'8+J4"EA4Z6;V>-?A*55 534044'- 4/!*6",."11.2!&, *-/.*--./1-/0+*1+%+*10-.,./,0-.40-/,2+0.1/*(.)).-*.&-&2$%'92','!/)2& /)3*0&-%3).&("1! 2&$5%0),("/$!+."++!,%!.((('))* &()'#&1**,2&7,2. 4- 2.7-";-!93:/!4/6,)*8&D1/33-!22"66:8'/9*9<$0A(-@,38/JG+EX)2H-8<%:A!6D"0H':;!8:GB$CN%9K'@S*JS(EJ)?PDHBP%BJ$>I&:G2K66>6.J449>B:?H.Z,3A51<<6@5?=/?G.H1IC6>D3.D6--93J).4%:8BB=7..!17'36?="E;$ED2% -5>/X,/,-31 "'"($$01Ld)S398>8I*JN;f}Sz5:[4c[0WtKt„A#r7& "% +!( 3-9<.++()473-0%B@I3>H-:() &j4£™J—£m¤»~œ²‘”± k𔓩}mˆcu¤i{a{¤o:`O`]8ZeOoŠBRafZgCXkP”~i–³‰¤Ž¬w“±eŠfªÝS›×B£Ôxƒ²a{¸¢lœ‘µ^šÌ;Œr[rª\TuQYkfjju½Š|°Šk}E[fmep?(h $ 1ss-_hD†Lp¤kBH;x~/Ú¶eÙ¶wãÿs½ÏXÿÿÿŸÿœ ‹¸Ïÿn¢­·i=j !#16(>*0%D`9¹Ç”ÅÏóÄÚ¢ÉÚo818:)6>.2B -!1<21%$9*%)*+&+>(/J\4dy&7I#DM*FO,fd!xgeVk{šž¦Å{¡¹D\Sy©Ð “»‘§ÃX¢°/š&qv'FU&*5<:H#T\FP0J!EE9XqIJU5Sa#KT&080EJ*6>*ds:h“*hh HB.0754BBUiE?YDDZAShIUwC¨¾xŠÀy™Ð‹šÜw©Ù]zž_€¤n˜±n¼æx¾â6xx(T.>_DNd7N`'3B-:-8"/="3;$1A//&A^I\|4Tj(5F% # $ '9%!1!,<)8P5Wr9GN)<@+::0/[0<]>'H>.W>%@D!17(24 /5 23 05".5 )/#00+3..1- 22-2$92#27#51#12 56!09!43"3198!5;"68#5:3;0; 4732#/9 48!86!3:.7 14 (43'*5%#,#+*/*.-0(/.1' //.)!(%$+"'!"&'%# " & (' .(1( ..-+ ,(/*0.&-!(!0+ .22/!7.!8/%3-&=-"83"9/!3-"6&A314(70.03+707-$D97:#<3%7/-4;53=@2-;%21 .9'.9)79$9>'7D-/G28B1>E%EK1>N5=H62.4#AA#8;&Cj.6S84F4/C)16<08+G>-6J-2I798 3@%->!3:'7>,Q1#7)#,3#$)1&7+$,((!     ')1)#>B'=N6/#$!B3+0)"-31 &%-3;--E:.7#69#4='4>-?;*%<5:-*3X8UH)’‘•›)t“I})42LS*2S:>'7f#=Kux[CWCALOC`Odq[lrAZmFt„AA[{Oh”‡}k”‹…¯‹Eqoy{Œ´Ê‡—¡‰xŠ{s~am…[µ”U—´t|†i€¨c?j:?S;`mEzs”›o™”¤´UAU6P*5C'73/:/0&%!!&*72$IE5?%.F=SgMg.v9Gi74RT-KcSwh´åid‰wy‰QFH]It|n‡‡´†ˆ¸s0PS9LH&8+3>.5''1*5C=9O&16,IX9\x5*8+7U,>M';F$IU+WQ/WkQKgEXmE‚lEcl0:=1,G62?,5>6Te@euGPxf2TW6Kd7Y[Ek\^ƒCau^„žd¨‚›È„éÿ^»Î1=S!.4,2.Hd_{¬BSq01A(9E'$0(>&>Z$09&+:)$2& +1-?<#8JMfF'<,*'!/%2@ -6#BS7_t3~‹:XlDKf02D&3D'@K':L'>M$08'.6$.2=7;96'A5$?9(78",8&45$0319 /8"6/69!6:&69&;.":6#58%5=&7<&15*0:!>7'>>)7G(0>%37'3;%9>%9D$:@*0?&26%1>%18)4>(26'9769$39'8:/6-,384>7952#6: 4;!67!0:!25!/4"445= 0:!&/,0.05/ 17#14!+4#6+20 2* 1* 6*,'7*++ -#.&6,!9-8- @5$=8$93';4 94";7%230-"7&9'++3%"=1'@,"@5 29"*17,%62!A3(,'*!,( +     @,Q!EPad@a’?1P3-<1 :"&#   , ' '(5,->!2?34Us635wl3‡ƒ]ž{nž³u›·Š•¯}¤¯y„¿yWhLF`HSXC\aOJT$PWdPo7Gg176.YQIk‚^m‰Kz™x}¤GŽ©F¦}‰•Y– qtƒP˜eY–™s¬ŒH}f—°W=si_dz—Õ|rMÅ¢b®®1¹,]8NH+R:='705(9B9AW!+2 '3)E0@Vr“@)@8.>+;H(3J!-74I(Me.;M'NQ KJ/88>&-#(5.-<#))07E%?S+[eAeWh›NWqR2QW/Yj/GQ#.=<-7E)4?*:;+8@$<<'=?"97!I6#Y@"I;/K/3F=0N98IB8t<-QN.JB39B).2*<3$B=!F:(@:#CC'S3%;=%D7*96!F6(?:$BA'D?%F:&A?(D@%B>(?B,8?*8:&@A(AI(?B.AC-8C*;8'D:$<<&8>)68':(.=#.;&7;%1>'97#73 77 5:!6>$0>*/9 .81548.8!146:#,8 54/8!:4"45"65!0-5.!6-:1,, 6+!0+$9-$>-)>.%=/"73%90%>."?5 :1#=0 <1(72!4)!&(!/0"64%;48?!=:#<9$@<&3>"74B6!CK('D8":F%;B)>G"?C+BB+HI*@I/ML)FO3OP1J['BR!WG$PG)AX/A=,8F#I5(@<&PBLG#=C(@M+0F4B<8;E--:&!1!%%*%!"      %,-%  +  + +  ,%8=&7@%9E)5)#!!+4),"NH>v§LVNBp9BV6ShC"Q?"/E7@1ML\f(GY5^8E(IN,\X@DU1(;,4)&&#  +   ((&4=/hƒJjxGI\(@O7RMUewnc€jIVsQ_wSkm©t“°j_viu‰\‚Hkt‹:oŽV}x8­·M¤ºk­Âq¤ÊŽ°Ñ’£³‹~¥ljŠ>8b6,/:60a[6p’Z~¥€²Ärÿé†ÿÿX´ò[žô|R¦”dƒpgS@à§sŸÈž‡¤ˆiViiRÜÑ­Ùfœ…ßè„·Òc_„q$/8#*008B,5?E[vQ¯Ç›ƒ²f{WH]JAgj‚£]Œ¨Tl€‚‘Àx¼q©Ïuˆ·ƒz±Z,W_?`:_f-FU 4;&4;;(.8>&@Q1~‡Qœ¬V©_Id>KE0X^AFiY¡[|˜EPk8GR!AP&(:,QZ$%;!-"';.<2>3:&9:*7B)9;*9?7FSSOovB\>6E",5,;)?!+=0F&IW/-<2A!3Q0Le9D_'ASCfk+Wc*IR&CS5B /<7@7E%Hc)Xf4>U?9S49A##->:PcBTk?AH6FX,1.<9&>>%5>&1=*97(8;):9#3:$4="/8#25#6434 79&3B)38(3:#19(66$C3!D??>"8<%<=!6F=8%,>$+6&,1"4.89$::#<@"8G'/EE/L;)C=.NC)PJ1LA6;D38?+=>(LC(EC,;:094-B8%>3'86*@=&:>&58$7B*>I)C9+I;0<=0B6'?8*??):*7A+850A<):E,A9+9>'?>&9?(C@(=E(7=&87!C="?F);9'7'-<%15#66%.5 21!68"8='68)6C(.<,19&/: 253:%4< 3B"2>'1D$3C$6?%4>"6B"-B$*:%+6%+9%7?#5?(8>%2?&/7'1-&4*'94);3*85'<>%77,22(:/#:3%88(E2&C1(D>%5D#;:$5F"1=&95&58$<8$FED(>E(97$E:OI!MJ'LH#@)K?%;@.;B2:;0:C1A@(9D05d)02YJRu*Tn5Hn0=Y"5N3L"QZ.Vd/=d'E/%!,  6616,+wVDT1>)*;37"P6[M%…rg|•oƒˆde„h€™y€št²ß¨és‡£It4“{@Jtuan{jlŽ£PH‘`e|raSAM@fo=IeR]pYQp5QcA=\;@@Vh‡dL€M`g`<`p@GuYkh“ÃpŠ‚_Un‹n~}|™{z·vY€…f‡‚ªcPxVO_36:zj0¡ŸL‚¡IYWMˆ‰‰‰â_µÔ@S^FZ]E[=tCI—DxazG‚w6Tg3@?KS^çÿµy¸xnŒ€‘ƽ°Û˜¢D< 1#$,18 #""-NKK]+7E0;G!??>FTU-;T'$&$%226A/_o:glUA]`UPC—›O»ÐAš¦7f~v˜¾³‰¯rXwGSX8EY?TatŸœes›`Iitm‰z…£{’¼‹§Äk‰/??6[iEq5hw#Mc*<,6;1-":@1JT_‘¢rt¥NZh-=S1Zi7DQ@fŠi…®Nn5@V+/D%/? -9($1++5A'-8(3.@!3D!AR*8I)7F$S3U["C< ';Sj9K[6X]:lb4XF//9+@I+;G.7#9 •;–< š<"ž©L<§O2ŸV<§X8¢L=ªH6£N7ŸS@¡M<¥O9«I4¦NA'&>8'C5!BI+;J0?B+8E&@H+CD'D(F@5D:+FB/9C1?A1CH)EB/FH'@F(AH-8;%G>%OO.VF4OG5JH,ID.>C*>D/?C.@B/7D.9>(:@$C@*CC+@:09C*;:)=8*>9%S<'=I)4D*6<(AD,DB%;8,7I1:4)8?":?0DD-EC-A?+;<'DD*CG+AC,HC)GG1LE0>I)D@7@>)CH(AH'FJ-BO(!;G'1<&7;*;8)8C$7@'7B%@I(>G.9F(/<+.9'3:!6A%;<&AI'1J&29>; 3C#18#4>'4B&2?(5;#32%36 38#3A%2?%34&88(87#;3%;:*9B'8B'3?+1:'7@,:<&;?*<:#?C <8 :A::+8=+9A,:G2ET"OKJP:J4'=(/+$"+, +0%-.+$&%!3&"      +   ( 23?7&,K(7F#$ 8"W4R2.^$/4&90TlRz§CC/F[0j•+zo(wœ=a‡5Yv4Sb'0S =PSS#Cb98J34E%.<%".4 4)%  2 /0-A;0>bXekbŒlwW$T‰ a|'p~Jœ°WŒ°h…¸eus[x›QR_bgcTfˆs‹ƒ¥Ð†¸ÊtwÌrUZI@S\BP_DJ.OictMx§fxŠ68uTY_8GMV=Q80J;3A-JW'7C?).6]QDU7eS=#P6% %43=AR•2MRBDKT]s~»},BK2C%K<KeNjpv6L„w8Xg,>J&8F&sv3µœ:ˆ*pmIFU_.(1>++9MY]T”ºAàòv¤˜¬¥®Ç„Š®ZwŸs{tbzDVsNMs3s{]„¹jN{XDo9JdFA]oŠ©”ºÛ›·\¡7ÙÎe¡ÈY†žB:E)./>/!(*A8)B9>usby‰Ldt88D0AR9Œ•;Œ–Ol†g„£EOa-8@,.$BGD@,2AI$AS(R[0H\+>L$MM!CK:H"AD%GQ$GY*Q[$=J?F9K$HS0BQ28C"BJ-AR-KaJQe>euDp…EexIoˆKv|?q|;w„?Zm5OcCYtBt‹Iq~@ž®9Ÿª2—5….KK*NKCGAD.=M:;H+;H ?G$AS-IS%18$17;8L9@P('."$'$!)++8)7:6813(* $,(;1BZ(MN./(($-.1JNR}‹N•z,NI+045K?@W?\kD]b?MZ8^]6PX1;I1˜IB˜MEŸSHšSH£RH RK RKšWN›PRšPLŽRN™IOœIL“UGŒHT•ES–GL”MN•RNˆSWNQ‰JNŽFS†BN‚EL‡ALŠEJ…@EŽEG‡FM„ELyEJrBAI=A">B$AD)@J,9E.,B-59*8?!=D-9@(=;,AF):L,CE+>H+GF19G+9F);A-?K+J.CC4JA+>G)8D/FC,BL,AK,GR,BH3:H+4D&=>$@J,LG.DN2?P5>A+:E.G*DD*;O,=E-6F)=C+BI'>L4?F3;D)BE,@G+AL*GQ-9A+?I)?I(8L+@M-=M0>N,@K,>V1=T/?M'NK,\P8L\5PJ:@C/(::'>C(<@/=?,66&;;%A;$E<';G&AB*4J/:;)<='AB+AL)CI*;L*=F&=>8G 7?%9G#5B$ED#;P%BG!>".B*-=%75 35":4;B'CD,8E1EH$;O59O,AI/@F*>F,=F,BQ.DL+P_2Od5`j=YX7Ng6TK,Hb+]^?YgF`oJbg+\m1Xi9F[6J2;C$$=(+($#*!2(1- )(. )" *-(%/6A9,7#*+!@A$:I+$H5010YPeS‹ \z8GmGFM3UV?v}.5D"AL!Pl(ir;]y!BS%IQ+3L4(?>*&6!%$6*1* @>^V"\mAfƒABZDNgMSEX‡nM–©U™y_‘tN[ml|JU]gT`7v‚Kˆ–W_œcbfŽlŽ|AaƒAOQN_U;PE5WR(4L"HM33 +*D@^^*SBH=!A77ZLQA^hJ[>'22A+AR/\_Ljqmº @laOVi>JS53@-N2BI6IP4KJ4ON4OR7NO6OM6LT4LT3KN8MO/OT/?P4FP/GM.CP/AP/DO-CL3CP.JQ/GL+AM)AL):K)O*=K+?M*?G);D+9C05AJ1BK4>Q)J0?F3:I/>L.EM.;I1GE5TO/ES1AK0;H-;H*:I/GJ/?O6?N18R)AI$DL)WU1ET2IT7=T+=M,AH-;O/8I.BJ(X(@L.AS0>R.9P/>K.@O07P0;H*8N.?M0DR@=R3T.>N.@D,1G,7C+A8-B@&AG&FP,AI0@O+>O0BE0BP.7Q.DI28Q,F>%BF'AU.?M3>I/8S-=@,=I,3B.A6$>;.DA#FN*BB.CI-CR4AJ0>L+0FV,ON+]J.WX.nt4Rg2CO0J]H^U:W`;fm:ZtBQo5bcBWs4_b=gd=SnBdiEwoFXtHMa-Qb&U„4bl@hk)qj>S€8`[-;]5%;$++*1('?-B@+=3C"3C,<03"(3=L'3= .C&+=4.G8:D*FF*=&;8"$)J3]V2|sR_bpœQtr3~t,W}/HhCCa0FX#[U"]Š4]qHVo3@k)3L1H\&NX4JT[[#En3IV2Q`DGD5]Y-R_+HaVY$-)::?,^V@`,7U/=C1Ug>e§cu{Sw…P¹;„£.«cˆ¨zTw^„H{ƒ.„‹Gf‡EvhLLu\bgƒj‡~Zg4ZfJd4JR5VqK0D#CN/1CT,?\;QRRLF;SGZDXQ1º§Xáè8‰­"-676;[„™O¾Úo©¾b‘ >~µER#T@‚y7„€Qˆ•L³¸Q|¬RXzHœJ‚–Jy{G©ß¥n§•Un„ƒ¼ž¬Á ¸Íp¶Åv§jw‰_~ŸJ…›Aoyv‹¦Ycx:c\@[eF9UF8G0ouI|¦w†¼‹ÎŒ€µ³ÕʮߪÑóm³Í@€7zŠ6ti5bg8Z\*nwQŽªa]u;iy3_QSf9JaGDbOUrlg‰WWZ)_U*m[7_a<[g?Yb6CJ)8F:Wa=_s;Yg.U_0c`4Xp=ZzPlˆGw˜L¤EYrDQ^`^7cf?jk6`c4V]Cpl6ah1ab*DQ(JX,MQ7DW6Q]3/ ,3'6E7LL7PY-;=:@7<7AY8QS&KS#;@52:4&.B+4.M?"9B0IR?agOLJn[o_M]F:VE6D4>?%;-6#0131*2.7.506/4+608+</?(O .G"+=#-8'1+-'1*0"1'.'1$7';$8)$>)+;&!:,"6+(:+)<+%=/"G8$DT,CP3EO0@L9>J1CE+O+7O57H6F16O/AG/DL/BO-SL1@a4EI1@K3=S3>I1AM2?S1?T2N,;I-.;='@G)?M1>M1?K*FQ1?U5=N0?@.?J$Z0HW3X3CR3@Y.BV.?X1>M/AQ/<\5DF/4I*=C.?M,DP1KM+=`3;M*;E'>E+FU0=T/=Q09N18H.Q0=U0GS.CW+?P0*9;/0;1:B-3H3:D/6@'3D/7D)=N+9L.W3CT/LU/C`:EM(MR3PS%BM@E"BC'7I#;=9D%=D(?A-HK'BT1DE5DF5MT4DY,CM=IR3Qd3Wd3OW4H[.OS(CG(HN8SV,CX8QPBVL;OKES^6VM;be4\Z2R];W[F_eE]j6enKQi;hwM[‚LbS8kyKb†T^c9\_1dk>a‚?}yThjET{_SZ<:_D4L'OM-B4>BF#7K-;?(/D.'@''3&&6$-0>0#CE-?;, + 6? 78*4A,7I38H!GHAD#793ivJI„SKD?<_hii\ZkCMT/dc/`j+q5U…Ns€@Eo6*K2A9EX(W8bl2ij0Bf7:F"I`5\T)o‡@eƒ;Kc6y†Kiƒ.yb&hv0[\ECh:5H$TH"‹z9Ž‘N{}DŠeˆ¦Œs˜­~W’ƒeŒ\…‘ly£z…—‡cžtB^YLeV8L[M]n-GF4:@usI`p6TjG@M JD*+DKOLa5Jg@9M5IV9'C3/D!'G#5+3-9@#JWLF.DWMC/;BA$MW"hc9iok>^OBE-_h?Ž–]^˜w-RY3D9-56&9%)Hf¢†sÅÉšÊã¢ÎÍž¿Z‹DoMS|Wss7‰Ž\I\{Zp”u‚……›£tœqaq7sŠCO^/CF3uŠV²ÜÅ¢ØÍ_’pL\Z*US+QaHVCN^KjƒayšUŒ Ccw;dq?tyAwŠH|€=xyHo}Ey…HsUyŠ_”—Yƒ•T“šK|M…‚J8[o9N_1N\@LbFZjGWsBZeTYdK[w^r’TuƒQyxMujEpsPh{Jjn8khFoqEqzCfr5\a0Y_7OS=Y\CT`.OH!??'=K.DZ8@G.1=*/=2VQ/ASAXw@[b2MV)5<(,&,0/]V*K\4fe=KPB>D@KJA5D2+;47<.=C%3/ .!8.$ ,#)6Wa.J0*7&(  '5 <8=:">;$8="?=%:A"=>&B;#CE%CK-BP7FK0HN3HP2EL0AW2?K2@I-FO+AR2@K2I.@K/CS8JN)AT4DM5HQ1JW-O]-DW2FR0AQ-?Q/AQ)FY,HW2;X4?M0CM-JQ21S96J1:P+DP5AQ1-:L25J3:G,@E%@"4H%/:)B:*8Q(:D.?L,AQ.AP*CT0=O,5J0BQ-IR36[8=J(@N4EU4>T5CS0=X+FS1DR)?U)KW'AS+IT*@a5IJ)>e/OW-RY7T^+Ib4QO8Ge=L`:L\:TI.\Z9Vi0Wf:MS:ZV-OI;LN.TT4KO8KK:SR9ZfGu^4V`=S[DYL>_PF^`9TeOS_;cVH`rPo>`oIYuJ\`F]wSehRc\W_j:EU58]'09!HT?2=BF)DL0CU!4A(;?%>;FC>@OD$Ob@>]6Q 90!65"FL+2C*/L17>1B[?KS2T|?RX`Jm:li1x†X—ÈL…ª>ƒ‹A4b7R"‡e%z’_r™myª[gjl‹ˆvl\Ž¥Dv`QA895YzRnN{j;KTJ<=8F8BT+)L<8G(>M#q€q9\,mw:@€<0E)$(>E!*%*&&Uk16a:@<0TM8R^Cpt3Zj(xˆFi|Tsjepn9x}1LiQOSf]aD')3@"3>"0?5"„dt]ƒŒ\n‘§’–ƃˆ·i•¿J…™F£ž[²~dv?NdbIWUHfd1IWIaWHOWxiJty1[OP__Š{||Œ—Pùÿ>EI.gbO {vR‰eŽ©rÉÝsž¼JZo5kCHbAœšTÃeeŠEm†0T`TPf[i‚mªÉmœ¼hXw[v“†£¿`d~Uv‰jvŽdl›d¼|°±„ªÅT¥‘?†<‘¦=”›;‡‰Vw¥vYŸ„µ£”´Š —Œ¶˜Üÿ«Ú¸¸â¸Áí»®çƒu“`ˆ©[}•JykBYY2[X3b\DaREˆAqv0WY4`q>uqKŠƒJtF†wO‘’Esr@{z>„B†s4zj:tlGho:guAvƒAby4`n6Zn?N`Qe{[y–]~ŽH€N‘ŠL|†Z“ LyDnP|No‚T“›_Ž¢WzŒg‰£`’Q€‰V„‘Dk{8`j:LV7J[D\nD^~B\xD`n>UegeŒhxŠ`—šWxVoyUrwQo{M}‚Sz~TnsQu~Fms>msCkk@kh>\V9`e3dX/NW7RW5UV+DD%553@O,US@l|JN[>DN3DS"17 +52Q)C@.>H+EE-:G0?J2FG3FO1KS6IY/LZQ2:G8IK1HM+NT/LV/MT2;U7DL36M*P0>P./Q5=E2>N+KJ-DW6:W54L3=G3HK)JY3CZ2@W.KR/K\0G_3H+HM/K-9M478099*?9$=M-BE0E-7J(8A,;B.FD*=N.GE+L2?N1?T*=X3>O5ET2CU9@S0LY@Cb/Dc:S_.J\>JhZi;Lc3P_3Nd-Fg5XZ1]`1Yf+cP1H]=QGIPnE]Z6c[\qJSc1fo,^†:dq:]7bq1[uKNV8Eq9OJ\FYG1FGAM.H`07\*,E$'1$aZY]~jWrc^zV\wOu}NT‰AKi9HnDj~NnƒAfx@\r7€z@Œ’Hz‹;_Ir†@Qa5GR1xŽP‘kpŸ`aYb†`o}nu’Vh‹xjqHl‡>Waf„q‚ZwŠu ¼FšžR§²EbrOpŽa›†„¯—lž‡§œÀŽ‹¥gW„PQwI]ƒDrˆfjlªÂнßz¶ÍŸ¥~‡’{|„–ftpN^Os‚^ƒ™Z¢ªQ‚z@ŽvAokAgYIptPoyNvD‰•L…N”ŒT€Odf[fsOehL„{U‹U‹K›F‘‹I‹GuuCuqPcnD~–Nq„Bmu?lz[‚’\t“^}†Z™”b{‰[u_‡‡Iˆ…QzƒU€Žb—©e‚˜U~Š[ydu”S„•W|ˆV~†Gvq)  +  $ " 7>4?D CF/@J4CB6FJ1>N2BD2DL/CM3=H/>F1AH4GN.KS1FW5HR;PNBK1IH)HZ'JP)OO&BY(CS+DO,>T*?J$FG#HY0>U.FN2Y\2Gd>GV2UW5Gc5IU5HY1D^?D7HW:Jc=OW@I]=Yd?IgCOd@D[5LX>JR0QY2Be>Hc.W]?E^BTF1Xa<>S-B^9U_7MnC^h6Wu6PWB^h>\dIV[8fnF`lEY^BnhCWqEQZ:[dQmJjHh;_p.Ql6[gEfs?}˜Pat;vuBh–S\oH\o`l‰N_R`_HtwC›=n€.S‚6^_F\Xr}^m?_u8n„=GV:X~At€JZ}:Sa,kg=€tQjƒKr„A€—l}¥v¡¿jhŸDTsRd~Ioh?ˆ™Uxªzg€ml‚H‰Jz—mIxcsƒlh‰z:Tq0AKO\eWY3^^-jj7OZ13G-7<-RV%\s+XmCGn&KK$Ugt?7=U$%!-*-*$!33 +%%*(##(=68o^‚‡A^N2DETo8KYlpƒšQ]jŠKxIgfjœv£Æ±{`:=PGJ]Y™€Íîx‰±q~£Cv†P‚‡W`xZqu\u„vyœmGiK`v5Op0Vp;Z~:SqK‚œ—œÏ”£Çu¸Ábަa…œM‰—=bsB’fŒªgŽžw{ŽW”ZvjIgmFH_A-9JH?UOK_.:>') '*')9'>:-97/310F 'tf1"@2;+(6#     2=3A:#<;,=@1F:0>L*=I5D1VO1X_/OU0KO4NK0SL.WP/PS8LZ:GE.ND*bH(TZ7BTGEL7FK3RY,]X>SbAJS;>T6R-5F(7F)9G)8N-1G/??+;S7AK+=M!=P%TL-MT3@Y-?M+BN$AP0OX&LY.I]5DP6EG4GZ7EY?PW:H]6LW6Nb3Sd1Rb8TY6Vi?Me8NW4L[9EV?XP/FW-[G=WU3FFFRM9MQ4NH:W\7RV;eKA`bw‰K`U[uJg|Bh{Ko~P˜X”Pi—Xe…]†œN_šP{(]8d‚FŽIv™?ni*LV;yyCkzVEg>€‰4[—'f{(gŒEl…B{’:Nw=LtE}„6jŽ0Wa?[m@cw9r~Gj‘Xk}O‹…B£X °\m–nwtdOƒTe„MxmIeƒgc†^ckUa‹b[‘bP_xg–fW yJaTWp,_2>d8RgGXvZK_Q5T>T\(HZ.8OFnJ;l—H%`;88?+Q=J>,2# "#&;78CB]"1T1C4C -/ %<.:7-=D"@A@,A&*.60&')%FMMC*N\K£ŽC;c(LI/2X.22 U_:Xs8k‘dY|zy¢€š¡‰‡®„‡ž[CZB0:<,=o18X;e5fo3˜¦Y§Òy¤ËŒ^—“8\"'#%,"&.2-lU>DEqJkZibXŒ¨|¹ß€—h`jb¦pH]f`nbAUxEJP0”‘W£bxWTpbDbRO`iWmD7C+6<clJx‰Pw…IoZ‰ža”hn†`q’FlˆQg„||¤o|ˆfsƒ{‹˜^YŒOvxPksZqZr{Yn{\…n‹i”m…›g†£Wv…O‚~QwzLb{XgxUu€fuŠizˆhk}‰f„beuAO_LVt\p’j£S~9QM&1:/BL$7C)3=23C30A78<&, &0#!<--, <=;H>.>>+:A19<2:6/A#'`^*"=157+61-&-,!( 4IU>RO9RZ3N\:F_9NSKaALX6OM1JP.VN5S99I0KJ+=U'FO4VY+S_0VU0QL3GY0L[3OZ6A\79P.2L2:G';J%NL'T[-Od1M\?MW7:f1TP5H[5\P/Fj+BT5YO-Od1LS6Q\0Fe;QX4Pg9Pd:JY@FS/IT HX,W\9\kEWi@Qh$Nd6b\5SqMp>GW3n[2OuIKi8Ng?di;Qp:Gg/H]4J_5^rDis8JpAbf;J}?FeFg4OX3E^8Vd>Wo>\dDGjAG`9H^;J`2Ok6Ok>Oc5V=Mj7QO$OU.EY+KK/GN1FS/JPHRE+RO4SK/TN3PP3Zk@ZXDWiPi]HhlJ^mR_`F^}dcwW‡Ql†KcqSJyPKV;WkD_„N_†Tg}dk”plYwbrx]qP}–]V€~B…ƒSŠž`€¶Wƒ:³Eš ]”¦MŽ¡;|‹eu€TuAq›G`’NN|Ifh;VJ]e\Ol=[w;_o1x’AŽ’OxµDl’cQ€\JwtbhupT`xE`xUNnK~tMdhPjVQmaHaTOR8C_j*@%Zj9ˆŒHSn>I^:aXMxvb‡Ìgn“dfhFt™'0-" VF<œžc¢Ê‰‡©’a¢#.A/&.656C>a\3{hUBM267/av_£³‹‚µ‰”¯_U…kY’ˆh{Ab‘EXq>C[-@WLf‘rb‡cOwN;N8@X0rgHƒ™Hsˆ-BS,S[FhXµá¤g ‰ƒ>—ŽF’Ÿ,^^7•“\bn™^‰¶‡ª”ެgg}5i{:F[=gr`]ueYoI†Xg™_n¢Y•¥[¨¾h¬Ñ“×ÿ¢àÿ†§Xf„[c‰sT’§S£Ÿh‹§pެ}¢¼q©¸|£Æv¤·lŸ¢y·už«aŠ˜až—`šŽT’’Xƒ]„{U†Oq‹Z¦§ošºk‘¥v»Ïl·º[‘œS…V€e‡¡p–©iškpžq€›v•e¡PQ‡š]‚œQzˆJ}Y‚•c¢§d‘Ÿgk}‘dnZw‡Xu’VpŽ`jŽj~]nou€‰~¹²g‚¨TIszOpKixIk~b}ˆhŒŽ`xŒkˆ˜lœ¤Zt‰U‚†QrsKjuN]|\wŽq|—e€šVZhbhbixHadB]h^]unŽszˆCQQ(@G2IU-8@'.=.9A+9;/,5'."2<"9%!2 A.>?">J/43HD1?D15K,8I2=G)?G/=F.OD*EU1=X4HI3QP.MT4GR:OG=QS9KSDMS:jM=ZQ8WM>UY=YU7TW5RV4E^?HR=LQ5VT5UM4JZ2GS>CT7OS4J];MU@JU9LS4MX5MY9T^PT2W[6SZ5W[6Ti9C]:AR2QT-F`I`6Fb4Q^8R`0Oj?O]9XtASg?T]8Q^9Zd6Sq:XoARk=Wd?Rf=NbCHhDQ`DPi4Sc8OsBP\CPdBNk8dd3ut8U€DWfD^l3Vh?^g\dAQn7`c9Xv6Yt_u9Qu9E^8U`>UmW’Sjh[}‘l…|U{‘Mk—H–FsŽUaK[ŽW@gMKb;ER4_jG`m_oxi[ˆIA]B^YQ]wzCk0J9.€‰;… BI«3)>"EQzSP¢2}«J}±;L\ ):"3!'$*%)"),)W#  +   +ECO;[R+(.5EM2DVNk66=#$)&, F.Dd7< KHJRFE?;[i/q€9Vo-h}9EH3Ši6„‘H‹ŸeŽœ2¨Àe“Íw³LVˆ=kvLV‚`pˆcxqg-CQ,9I:iwC@T3hx+fy.^aX{•W@C4SI+xˆ:QRTN‚eXa`Q_:T_Y@LsOYe˜Q{…Ev3LYES`GiyP^ui—:«­Zr…s“¬y“ÁºÜÿµàÿ §ÊTk6kjOu—Pn˜ ÌŽ¿ÁcŸjª®qŸ©w›¶x•«l³l¤ªr£¢lŸh‘¢k«n•¢]‚šSyGj}J‡}¿Ü”§×†’¬ˆ¨É¦Ïü‹±Òd’–cn“gƒ¡qn”oˆ«^ЦepT|•f‘³j’ª]‰™m•£`‹™[§^„©tœ³ut›huŠ_{‰TguT^qSp~Ss•]{˜c{ZwŠ]}ƒh€†gˆ¡b„˜Mu‡KuŽN˜Qƒœd§p©·Zz‚a{™lš_a‡šT„‹PswEpUo’gf“em“VˆƒMaxWYsRepM`oS_s\Xp\UdF:G2V_5Rf0LQ!4;(>G.IG(?>-1%8@56&  / <,;D#@E06E09E/;E/>@)D-"D K"@$%7$'B8)HH0>H4>G49I&>?CBLH@J%>M,ED&GI+AG*@E,@G*ND)AO.>F*HE0FP.GS\H6QT5UU:VU;ZX=Y[9_\>KgIJS>OK1IT3PR7PZ3=T6AK2MK0KJ+DS3GT0JT5AU6AS6LV2OU8TX9W]5H[5QX=H^6H_7@\:=P7IR-AW6FS6F]2NS.HX)LX5VS4Y\3VZ5Wa/QpZk6Wu?LeIfDX^7Vi5tg;j‡BQ‡YekKU€8`qt@PUDIsAYX=am8IkDL];cf8tzE^/i`Biv7Q~IYj;KaLWT>Ux/Hj=eg9O6LVzd@QpAQhEZiENuB]e>cxJP~?^kKYx8V]6ug0O;VS5PX)V`.Rb?Se3OU.Nc6Jb9Zi9M]?Rb;Tv?Qf6Z_-[a=Rm@_|EXp9[a1^|B]jBY{C\o>[l8Zr>SqCdrAfyITr:ay7an;[|@PrAQc5Zp3Wo6Kf6Yn6V{>jrA\xG_nOdˆ_cyPe„Alt>eXOjS}a[wKp€WRxV]~^^|P_El‹U€šQ€‹7vŠD€™dª˜av¾S„‡H{¡T޳P©NŸN‚¡e’¦R¶v–¢j›g–š^w yˆ°qвa}ªs”¯g”»i§ÀƒŸ´G¯¼l‡¯R¢px—]~—V—›Sw¶Y†žF‚–)±Jfª7o~FEÐ>WL>VnfLM0MU;(B]=UKQ\0RcCbq'ULX&!"1=.7…ªf6]Z;:V;G;LtgRžRŽŒH’»eoaw|u™qŒœogi„bm†Ga–RCV9;APŠg¡àXz…XVjLv‡LžÃ{Šª°¢ãp~¡b‹–j¬­R£S‘²qžÎ€\Žq7H.AP+CPGI!LMFOW>‰™†gˆ™NtPUˆ™1AS,Q\/jlKkh*@IptD}›Kz„7bpVnƒE=TB\YPHF'{s?ZfB[W7>F-LQ4iƒn|Œwˆ ‡„—MNk0MH+OK7O]At†Rl‰hŒ–m“«Fho7HZ4HZ?ENLcZo‘`b{V®³ct”rŒº©Æ¥›Ðc„–F]rTadެ—·°®Å¢™½‹žÀŒ›·}žªp¡«dÅÂ|¶Ó€Édž²¸x¦±v¦­yŽœk˜Z†¤a‹ªe ½‹§¡¥„±w¹œ–Ï© ×‚¨»nžY{š\z”rž³_‹gŸ«T…£c”²n Êp¤¸i¡¯v ²fªb…ªr¦Àg¬Tr~U‘W|“HjxN}ŽSe~[z‘g|“amŒfˆ•VyŒd†˜`‚žVsŒb£­r ºx¶lo”„‚®jŒ¬U}—g‹›_˜q†¡fˆªa€žOsŒWi„Se{UUn]ƒSpQ]rV]{VM]OYoPc|R~;R\Crx@XbGZf7TT/HG4GP/HR(RZ"8>>3& < C4 +<>!BC-AI.@J.7I+=E-=4&=":9"7C4FH(GI,CK0AJ1LJ)NH*IH,QK0P]3VQ2LM-PN3SH0VU0XW-H]0LQ8HP2RV/V[4`W<^\8_W:QZ=SX@TT4LWYtAZn5Q}QZkOdw0nŒ@_‘RXƒDfo=_‹5go3LvBEY.Rc3^f=Ms<_iCO}AYf5Sp@PjHKuESdcj9apC]q0co>Zƒ?kn4lxL]{;Zi:WvCOj>ToC[‚NWnS\8ak8fz4qw8U@J^1Zc@Rp9Kob~4OtGKl;Z{Tak8NyHQk@IfJei@O~LgzCKdgzB]{J^=pƒHQLXh8jCP‰XdwGh‚XiyXg‡^‚‡]‰‘a‹Ç p€XŠ¡]’¤n~ŽnsÀc‡›_„¤|~–rwŸvr©m‰ c’Át£¿u޲k¬iš°_±}”³}š¼{аo“ǬÂpãx•¿Z£»m„»ˆ¬´—Îe‚£m›fˆ¿_‘¿…s‘D„šVšFŽ:u†"u{&MY*/CL`j&XFk;f{!>K15Mf@W-Yu80W'DF/,B)27 6XBC+Vj.5J'," #) !. %>*2(108 -"%H:,73,A1)$GP:FP[QB eUK€"*3)JS4T^'alLx‚L„…,|”,‰—MmŒtƒµ‚’—}ÉZ^`KNkRIJQvNPbS†rr¤[}‹;Vb'gfh`’qGEAj|A‘XyœpdŽ[Wb^…vSµ­m¹Ü€¯®eÉ瀮ç~ošIw™9Rg5V]?jy?eg=Ys8Gb[5JB/@/(?PVƒk’HnŽLz‘g‡—a‚‹,g]^qY{|‡ž{„¦fr‰7TxI2F2LOHQ^;G_:BX,PUA³¥KƒŒRj†U?LQ[S/Š›@fpP]|Jjva•›b´ÆpNiW=E5JU3=I,?C,W[DtŠ>jtPk~l]iPp†^t_rŽd^€ITn6CTMJ\jw‡ƒŠ§’Ž’r‰‹ª¶ˆÁÚz¬½v¼Ë¿ÓªÅÙ±°Å¢«»}¿Æj˜§p¡´tŸ¾e‡‘p­½{бm‡žl~•h‹­k„˜|v£’…¹r†¥pX…šr®Çz©¶l˜³gz˜]x—v¬É¶Ñw©µs©nš¸n›³w¬¹®Èd~˜\s‡J\tFYoKn}Mq}TŽY}WrŠe~“Vu‹`‚žXz›X~™qœ¸‰‡¤uw—dfzo~š~—º`z›`y—^x–e‚¥t€¬ks]}Œ[v‹VyF\bPanIR_OaqTv{QXmJgrM[{`l€NLX\zHT^@KUDMZ7AF3Q`7I]Pv”>r{?,&  +B E9:E%@A.AE.AG.DI/EE-?:'91#0BF3CL+GJ(EM-II0NO/OL0MR1WQ3Z[6WPSX:IPY-EW2HO2JY+I\3L]3KZ.V[-Tc0Oc5Q_:Rg;I]=Fc3B_8CY5LP-R^)G^4E[2CR,LU,G],DY3JP&EX.@X4PS8Q`@OcDIc?C]5O_2B`,FT.HZ3S]*kg-[~5@j;E^4LT2Od*A_:HZ0P\7?]5P](Qj8Gb>K]1R[6Nk2Ca6H^4N\+Jf4Fb=FZ(E[=T_2\l.No:Og-M\4UW6Ke0K]4Fb7;a3O\4MiFZk>On=gf/[}AjfDc@d=[‰IVqU_qLr‡GT’DanHH}IKc:Wq5Kh>PsBMr>WtAb{>]rBr6Hw?e]7a‚6^ŽHZnCYy1gmAg~5U|PbqCLxH]p6oŽOi‚DlŽF`™FLoKjk=`‰F\€Fn„Qg”NlƒGj”Ma‹BZ‚:w‚5X„Kp};WwL`iJ\c7Wg:pm1rr@f„>ax8ju7j…EUmH_€JUyQIgy‰Hf€HKm8az=d€=Ow:]p4aw?gy8W}5^oA]‚?XoIyLt…:c‡XRvDY}LLnAfyPcy7`}Ah}Vx…@r$"3%1QA%Xi=iy*7C.?"A@,_W<}Šbm?3<mL¤„/GY>UL:ˆ¬\mrkŠ¢lrŽo[mzœda†h^vil‰HYuIa†At³…bhE› pD`UY`p`xLVrUdhO¡D³YUwv?aQf|UAa9`po… y–¼{𤔙µ’nsoZš›`‹°Au”?WoLc‡QrŠNBg4Rk(;B.C 075BLKns^Š¡S„yir–\ZyFLi9R_8@WvluwTER0id'rw9‚™:w.Z`.vs8€‹msnVcvOªKs—W)EI$3AG[Bq‰b`pb\b}F[-Y[0§§H—£1=I-APIZj<Š—Mƒ Dž<€P‹£W{§_sŠM•´>[m,UaC†’i|–k’£V€Œ_§´…Ê܀ªÄ†®Å~Ä’ȼ‘¬³›§¼œÎÜ“±Ã‘¸è–¾Ûv¼ß„Šªiƒšbƒ–_h…bt‡cw‰ge‡hg‡ja€\u•o†–§œ»r‡«J˜o­’𴇋³o‰©|ޤw‚£v—À‡–®t€Ž\|Eh;iwBszKŽ¢Qw‡]|X€—[ˆ“Nwƒ\l€]o”dЧu ¸x‰²d„–PtŠVsŽu…¥isŽZzŸnŒ­i‡ªq| eo…_wŽYlƒfwNxŠ>l|A]oT‚Ÿi’žaq…Xw…F[sSHX@JNM]bFlj:]bDbm:QO>e‚LezjƒœlŽªN * + < >4C>'5@09:)G>(CA/DE,?:04!#$&4>'AG)HE,DJ)HC)MC+HJ1WF4TJ3TH7^IT(NO0Md7NY/K]1N_7H_.L[/Fh7M]9Ke,Dc8M]/Uc1Nc4Qe/XlArBUR3hg7bz6Wn7Sk6TY2Pf,\i7Tr@Pl7Hg0RR/]f6T{4Jj;CS.R`*Jl8^c7Sw@js6b}DX{JIsHIjGZpN^wWXrGLtFXgHXnA_t@[p?^q6Oj>Go3M`vr3‹GUŠAW|CI‡LfjDa€E[zINzAPr=`tG\„>Z…Vky8rŠD\€=d{:nNm„Uaw?{~B}ŠA}Š?Zˆ7Nn@]l;]r/f‚9P†?Tn6ad6\vNe{Iv{Me…QsxOq£OZ‰L^ƒUm|HV†Gip;eF]B]j3hrHw…IqˆQqˆVS€Pj{TiŒPYƒCYp>m{WŠ8Pj6Kc/GLPddL­F† I|™\yµi’¼Ks‘TŠ¥kYˆQgxH„•VžÌ_v30AADewJŸ¹pau:bx>y„=‰£Z«½‚¸Ú€Â×< ¯R3@J.9I(CI-AG+=P,;P29J86J2AJ+]P/kV1\T4NT=LS=FU6GR7N[1Y[4NZ:AZ3>U0LJ.S^,T`9Ve4Hd4BT1:U);N/CP)FX+K\/Za6G]5ZZ5Fc6OcGDc4QV8N].Ba0BR4NT+B]&C[,BV)GV1OX2Mb3Kc1Mc6I]3Ha9E\9B\->_6<[0L\,\b7Qsfv>_†J~~K{Ÿ?\—>mu6sƒQV‰OYs:QˆK^‚+k}JZ…Ajz>YŠ;]ƒ2Rq9hwFM‰>UtAf‰GbJYyDgwKUDdlDs›he“di[jHn„:iIZ†F_~HWy4Qy7Z}I_v9Z{BirUi˜Is‹^s„Mk‡CUs=Pr9cu8_Cf‚JfƒžDjzEuƒHožGt‚Io”An—Pp‰SnŽG€ˆ@…¡I†·DrªY†Ÿ8wƒH€˜J‡–@s‹Im‡@`Š7w…A”¦Mt¶Bu†BhKv@{¥^”HŒ¤i…˜Rq¥€zE¡§U¥R†¥T‚ªLk£H™‘QÊLcˆMŠ”Du¢E„˜Up¢\j—h“NrŠYqœw˜Ÿ‡›¯ex­}sŸXr‹q}„£Ï—Æ‘“¶žƒ ‘ºá°”³„ƒ©}•‘®~ž×w£È‘—윤¹l˜²u„Ïy™¤”žWoœtšU„¤‚…§xŒ£}~¢˜¬¼„š½•¬Ñ‚“½ ¢á±Ï˜ŸÍ‚‘c‹Q™™×Ès‹¼SÑÊ[Öôy¸Ñ^Àí‚´ÏrÃÿW¤ÒG£±G £T©N€£|·³f‘’Fœžl„œK°¯{˜Ÿž“Áváà–Æju{S}Œ-Œ¿Rb4dcOThM…“B„Eq•SctLq ^~–kGUwVwZfWgˆWF6V^<@QGj…\eˆnoƒF_‚Yg‰ptdq”c  + / &&&#%"$()$#9$+!!/<1D6!CA(80?;#E8.^=(XK/LN@OIA@N6GL1HM4FH?RL4XM.HT2FM9@J(DF*?E(C<$?G&>P/=L*9L.:G-NK#eM&XT1TP??TV3KN.JV0>W2HQ8FU4IO'KV)O`5R_=Bd?HQ4EW/BQ1;R(?U+GT*QU-Oa4LY5H\3H^?IU4D^5AX6E\9EW/I^0H`1IZ1LY,B[1eT1F}4J`7UaR^-^m:lh7a‚=M}GLg?C[;M`-Vh0Mp@Rc;JtPl6_rKKlRagDY{?JsW@bAnŠIc@^|@U{LotK|ŒEl˜Kp†rfNe|B^BPo2[u7fk>R<\lD[€DiwD]‚>f{KWo8Uo8PnA^oDouPMGLiHVi4RlM_zFZ†QOwPSmA^pKmgP_‚;WsCWl3bl?fˆKsŽ?qMbšE^…>P€;RtDo9e‚>n}I\}IqˆA \g;f‹Iiƒ\fzBY‰Oa‚JT{Lc{Fb‚>`…@f{;X4by?r‹;x—7|Pp‰PpŒLV‰MOwAZt=h…8eˆKt‡Kl…?d€=ŠzBv¡Jw“KŒ¦\}§DsƒBm’^~’K¨^ˆ›C¹G|£Qg¬YŠ‘H‘«S}°IŸDržSv„M}š]p˜Tz´V‚²SpœJ~Ÿg¤XšPkŒSgƒ?s¢f†©†_Jf…RqŠHh’So‹Gr‡^l…On‡J„œKsV‡¢[s Kj[r‰V’ž]fšŒŸ¬R˜·TÅii¢jr˜X„–]qŒV~“[zPkœT†¨Y…¼[Œ’U˜ŸM“¾S™Ìw±³‚p§h ¢J’¥{Áf}ªY—ªl­^ µ{¤»w”ÑœÕe|¡ky²{•«eŒ—d†®W¹T“°`ˆ±[€©S³T¦¬pž£Œ•·Ÿ¨ÑaŒ•¤Ç‹ÀÀ‡”²\‹›P–¸i¥Ó™—«u¬Ã‡ÎÔ®¬úŸ­Ì‘žj·ÁІ¶w©Ð¦§Éy—ºj¦ÉZ®Ù£¦»_´³fÚõsÌY Çr‘©¥{¨no”N¨XЏlÂÓq¶»b˜°Ox™bpbužT¦¤Lt€Wœ_um:mnA]v=œ¯h}¨1jxeWƒg˜•a…–LŒº~j‘ƒ„¤yGym„uFb‚\WqP`n€•B«®^uŸSŠ`•´†Œ­^muDWx3KZ"KO/qˆ8f…T`flš¥X†žTh€Fm…JLq1W~_ŸZ`‚bvž^€¢p|†ÑOk’]bPSt;aoFhy=QbA]jLcoZQk>py-ki9YtG_qF„Ÿ?bxGt’Tb„^‰rzœr¥µ¬y¢Nac0«K ÂŠÑüʳ尛ÃÉ ßǢƬÑêzh|apŽn£²ª…¯ƒÍèiЦW”i‹ŸoÅÎs¢Ug€WW}AYsLBa7Nfdˆ›Mˆ—T€‹8IjEOhVe€YmŒWpREa<[tJe…HTp:XnFbzTd‚Ba|LqŠLZ|Qj~DOcH_ySzœPp†P`uNt„UlAjwKPhIWb7;=5j~3Yk=cƒK^vWHXElqGcq\_vZTkS   + #6"-"'/&:-75"0:'16%55!83#G<&[C(WI8MA8>H2K6BA*LB'JG(O<(AL&>G-R.OO+C])ET+UW(H]&F[:OZ2M],I_9G]2H_6IY0N[0FY,QY2@]1BX6MV0G\,v_0\“:WsDTm;Zm5Qt:Vj@Jx3W_/Ge)HT-?_(O^4Lc9Tb,bj@au>OzJSePVl0Jm4Jb.Ng;Pk@Io?Jc:Y_5Qr:Kf?gg?c{@ko>j‡MS€LPk/l\*d€/l{>g…;lJi„Bez8XxHTu>Yc=jr;n€?\Œ;hpBj|9Z…JhsFcˆ@W‚N_vGg~Ne–URƒQVqBTvDduEu~Oy [eZf~TV„LV{@LoDsj8_y>cAcsA^p;bs@ZrDanBczB\h2kn;Ty5ew;`L^l1Vx7\k=Zn7Zu8To;^l8f€9eo:~‘H}ˆGl„HV:Up?kw?‡†[s¢^[™GXvAbv5Hs/UkEdqFX…GCkªZP}f^uB[ˆ?Z{KSƒF]ƒC]}Bhˆ>g‚?_“XrˆCn‡Jˆœ8m“E…´SŸ©\e˜LoxEfŠCY9U|9h‚A‰DpKlƒKc›Bd}>tfbVc ^r”\X…NjvDf¦gg¥a‡‘]™ijÑpvž]w¢Dz¡Xz’Q}²Wx¦`tŽS’—V|²Nu„O‚žZt­l…šYÄd{~g„ºSy—MŠ¢[l—Z|‹EuPo™AiˆMyƒOm§NnNwCv†Ye±Ve…ZjŽWxŠ>Y†@}‡Ly•J‹y]~“_’w}¬‹¯ff¦SpNu–O…Dx Sq¦gŽ£y{—\o¡_¢_’Ö…‘¿tyŸYn‡Jƒ¦^¬qt [‹™h‚¥cŽ©g‰³w™šr£jvŽD–¶p£ÀVÁÖV”°rƒ»w¤¸o–Ût¥½U‡³R|•Zº[Ìb¢Ø{ŸÁe²æz²à‘¶×|§áf×o£Ø•™®av§slš|‰«“¨Ó•­ÜhµË€ _{²…vš‚šc­½ŠÇƒ•©qšÇ‰Ö£ž¬”œÍŽ´Ì‰”¼p£¨\¤ÂYªg¬ÈpÐÚ´îÿ•³ÕiŽªi¤Üd«Ò^£Ïy›µWv»c¸±c~¡XÐæF±Áa§“b˜¾Vƒ‘Aª®p^dlQaiSƒ·YPd-YqMXa=w’>|}B‰]t—”x£So¢`xœ|–³[†‘Fn‹C™©du£D~‘L‘žQ} N³cšÈi™Æ`·ILS5p>œ§hy­DzKk„\`—R`nOeŒGxŒJ©A¢¹W[};Vp?r‘?XnoIŠSŸ¡e©Â`´Û\œ·_±¸[¡R©m–Ãj€£c€¦f޶ƒ£Ãc˜ªP€•cy”ln•aj~C[qQb€Yg‚Xm…Zt’VayM_``Œci_bŠ…¢ÇŒ½ÍSt‰Ic‚e’®ns—]w‹R†‡E\b@Y_OZlKSc>Q?ZxIeGp‡Af|?Q^EUYBLYE\cEPcN        4#+!&#.0)03+4#+3!3-.991&S2Z<+S=4D@5A>5D6&FB'HA*IS(EL=LF.M@#EG'GF,OH(GI+>H1OF,IJ*II)BK,GK,LQ/CY7GN-KO1IQ.FZ3CR09K,`h?eCMHVb.RnAYj;YsxƒFk~@[„Jmqzºa}¡Q­P‰˜O~˜O^ŒI‹œX‚¸l”¯Dr²M†¡U’DxŒR «lÍG‚˜L ¯Vy¤_“£U”·Wz¨J—®Q} Y„´S–½a˜´W°ÐJºRšb›n¥cŠ P‚‘Aš–XqI€—Uµ\z”SƒŸ^ƒ¤l€“TŒœZsL‘›`Ž˜ek–„ uvœc}–f‘²~†Ã‰—q—¶Dv°m•ÎŽƒÉwœ¼r—у®Öª™É‹°Ú©ÔlÇÖkŸ¡k‰½f©ÄM¤¨O“¾€žÇ™œË|šSnM©×E„žSeŠ\ºr†¿k¦¿xz¢z½kŒÄ’³{“°x˜Äe˜±s­ÆS“¸¸ë’ÄæÄ¹á‰»æxàÿ˜¢ÆzŽÀyºÔwÏílƈ¸¤W–³‡«¾yukZ{ˆ¦b§Ì€Y†Edn?ƒC‚yX‰‹A†y=zdK{¤p g^yg¤t¨ghzFpnVa{…d‡†qˆX|“‹y˜^™»c¥mª¦dn‹`£ºnbnm‰–YœºE|¦dl“oTdMyfh…WO|Bˆ¨=s‘Oi‹_}lmœ|Pu=OfAV€g?q:AbEw—`z—Rš´t¤Rp‰Pb~Hb„?SsFpˆEuŽGt— J{”s…™……Ÿeq‡rj‰ok”q­tªÅwœ½ge‡hPtl¥qx tj|tÖã×¹Îgv‹csku~P|’RŽ<ŒA‡¢Ax~CTjMQhn]]VFQKoyMk{TvSgzak…act5HX4CT.EO9AM7:D,=D7m~I\>GW68FCn{PjzUr}Rd‰Si‡F`vEWhG[k>R`>R]J      +!* !% #"*%(&+#/*&+/2-@3L7'K9/BC2CB7B<,B?$=B'AH)OF5?O-AB,8F'BB,@N)?@2D=-P>,LG0HN3FG.>M.AJ6>V6EI1GO.FV4CV2OS,PZ3QP*GY)KX/G`.:Z0RO1Z\)Il;GY3HU.MX-MW1S_2Sh5Im6WX9Mj*Va-[o1dk<[o;[l7Lj5Kc:H[4k^*\{1Vr4af0er8MCWfANm6[h8Ys^|=_‚C[„MRsVGq?`h?S€DLj=Wm>Fq1fi7XyA[n=T}?gn>R‰ActCT;Jw:Ua2_~BlŽNd’^d|T]ƒK\yBgxJ]„>Rw2go:cwHUuDVk=^yAWu1NkE?l4Q`4^j/rŠVZ|NSyDXq3RrMj|?_‰En}Jm}:OSQaIbr2XxF_{G`nJbw?Yp>bn?Qw;]qRPs7Wf;l„=fzGY}7Sl2Ql8_o1U}@PpFrm1\Ž=Wy=co4Z‚:^vBW~Cl{Nn‹ie†ZX…UV~M`zD\~inl=R‡6Sr8_p1WHcs/jzAjŠAS‚.Pq5Ws>_…DWoEoq<`t@sPN‰Pjq8n~IZ‰BolIZCiqFm Zº´@vÜ~zˆDg€D”AX‹@n‰Na®uXCn‡ei}O†šDh¥‚p”S–Id–Eq¥W`ŠTb;CT@T_6Wz=bx^c”\ˆ·cc…kh’]„¤N‚®LeGbˆfy_‡›]zšX­k±Ìq‰³pzœX€œVjŽf¡y†«É¯Ñs|œLg~Rm„}” QxŒŠíÿ²Ät’URgLbmR|ŠZ`}kn{R\nWsP•Cdt3Sg5jmBVqXVmKZgF=QIBQLXh7NV0O\8hl-=N5L_1Z^/@UNt‹Eº°Q‘f¢Âº°ÑÿÿÿئºqÁÀcϺR€‹Qofˆ°r}Ÿlz—lx”rs•’–·~|‰ab~Yi|Rrcu‚wyœp„¢Kd{PUsTTnCa{@[sHe…KVnIJ\?Mb:Jf5MjE]~L‡§i‹±~{¡nq”[v˜Tn„UgvVYjNMU@HS1IS/GX2BY07FO`axˆRd{M[sK[rH\uJbsDWtJarA\aJ         %*&#""#"$&&'((+,---3:2C;$:D-B>3L?-?D!:B*A?%O?*8[,><1:?$G1IH+DZ3CM.MH)LX3IU2OT-QW.SY.M]1Ma6F^6E]0OQ1I])N`@G^:RY.Q_/N]-Kd4\`1Zm^nBaq}‰4k“D\‡Iapw†2k”Nv‡HQ‘Ihy7nŒDp‚D[y?lw9Qš@nu>i;x}Uc™>‚‡B{Ÿ=e4aw9`„?i‚:s“VbŠ?bŠ?\tH\…C`‚EWy;erL^uBc€CTx7Šj8dÀRd{3q€Ec†:u‰;py9\4cx9wŒDs‡=g‹4x4fš=vz2Y~.wznFX‚Y[rIm’Q]“EfyCj‹7‰EnˆBs•f†ˆP˜­]h†D˜€>|¯WrŒ4q‘\l”@q8n‘^m…FqŽEu•gn‰]gœun³ty“\p UrÂ`¤¥† Î^’Òd\r3nlZu„Yˆ¿pz©N–ª\˜ËˆŸVižZyŠ\¨ `„³Oz£Q¡®WpžR›¢Z©Ëg‹ßpy—S}J|¡V|©Pp’N¨[w¤Dz’[§­{€²\„™o{²a‰Ñh“ P£gd–Fy˜Cœ†P€­Vf€V§t¶h^~GbnF £V ¤X¨šI°¬os¶d€•ewT™py³[†’Wˆ°co¤Uy’[‚N¢k{¥bÙs|¼d…Áp˜Æw‡¿|‹­ˆ›»‹–çˆÄ£Ø…¿Æ{¹X¡Ê{¶å¤Í›²ùo±ÎdÆ]ºÒY™ªSš¸T”´]•®–z£st—[‡¦h”Ïqƒ¯v£x¡Ø‰É³£ÆŸÂ𳉷„o•€ˆ½”¤»´h•É€ºèZ§§VƒÁq£´ƒ”Á ²Þ„±ÙwŸËd|­ph„i—¢y­âg‹©q›´]Š»|›°Rš¼^˜¶Tz«W‰‘Is‡p¡ÁXm“]vHw“Dd4?`6Wl=qŠN€¢]t©Lq‘[©È}‰¸^i•Mp“Vm–sz¬u‹±f¬{|ªou—d‚´dX„Uh_†­q‡§ Š³’ƒ³\|°`XtQd‡cx¤–k“½DjY^}Us“BaK}‚8cm:Ul5o}4VqEOod{¢{¯sx—Ql”U`ŠVgSo‡IdtC^l0L]6G\6Rf,AP3GKSf{am‰TWaOakHYqK\sPk‚?UuRc‚Op…>      "()*"" #+"''($%'((/0.54.64?9)F<-PA)AJ,:D;5@(9?#7F'2>/3@%m?gŒVi†AaŒ^j‡f]ŒU^~LnKv˜Kv”MXšh_|Ro|?a‘\fDz†;pF|›S…¡Uq§SžFqšXi¤je]w“J–Kt¸Dj¢Xh~J]‡^b€At~Fn’[I„Q\mCS|Hbk8m•OpžJ\OpIZ­_xQ¨ZbŽDcH^ˆLp‡pl~?WBa}A{‚5oEA‘¢A|’AoŒQ…8©YgœDW}>awVG}^‹Qv‡@vŒP]˜\z‚It“Hg—S~Ov­Glš=pšV`“L_yJv€@vUw˜Gd‰Hg¢a{\v oi’Hv‰Re‰;d„Gz†Xd˜Vc†Q_x:‚C_˜D`‚A›¡K†¸Pœ¸F‚·HYŒ@fƒEn‹@p‘0€}Kw‹A„N—HgžGwhkS}Š?ŒºU¸·Y~¯Qs?dŒPm`|™v‘©]\…P€¢Jv†St`‰¤Zt~AEN3CU3FW>T^*;D.CPIGdaX~TVnEYsF_nN\mSXpFUwSs‡Tg:  + + +$(%& #&((("'($$'())1*1!,-!<. D:#J<%;H)7E48<%>=&EB"=G'6B%F@+EF&IF2MN3RJ.NS-YR6JY9FV1MX/[U8ypA\dBm`Fd{6GwFIW@UV3R[3Wg:]dc|HP|E[|Z[zTLwd_jFcmNYv>Yo=MlB[g8_m>ZwAUp=Uh@Qv9^sHV~SRtTIn@Yk:StIIn5Th;PqGdzIQƒDIrH]lHb{G`‡@S‡S^tIY~=?uj?q‚;|„@²L|–O|bv‘Nh‰Flˆ@ŠœJÆ\j§A†¤[žFŒ¥i¡¢C™°X‹­K€ TŸ­Nr©c`–Jo˜Pš…r‘­^›ÆŒš©b­˜‰¤¯ƒ—’¶\±¡Y{·FŠŽFx¬@Ÿ¨B‡ U˜¹`{“XfIˆ¯b˜³J…£Sy¨VužMn®TqŠH‰¿U|šP—U}¥]y‹N„ `zŒc“V~«O}©R…¥Od—Q|]y—Xt”Tv¥y‚Ÿ^€ªPžñvišUk‡Gg˜SjPv‘K–®o}™P|—Zo—Rm‰j‰œTv˜[w®Zj…O³c~£Z€¢g†¤Mwšf’™X±£u–«{m¦e¬D¢¸n¿y†©©o¨Õm›¶ˆ¬ÊXÂÉq„£q‰ÁsŒ l|žNg•W]n?oŽ?”Ho›K¦¨L¤¶¶ò}ÀÁš·â‘©fo“O¦²_©Õn¿ÎÁ¦•“®j¡c}œW‘¨]}¤e£·~ÃÝž¬Ño¦ÚkšÊ\˜¿^w±W”Ÿp‘³k•PsOnˆhknD‰™Zy›\RuIYwC\xBh„Fr–B{™M„±H‡šHpšJu¤TŒGq’Rh’gˆ°Z•È}œÓlv¬q_’`_{ir‘U¤dН^‡¬t_…][…_œ³^YwAQl-H^'G[Dcu@lDd†B|™Nf’UrŠYb|Iq—S¥Oh‹lН¢¸}©ab{fyHbyCl‡:[p8[tƒo˜­‘µ d”\‰›S¤Ã\q™;py:`qF‚P•¤c˜–cw‰mk‰\_‡o–ž~ž¤‰wˆ­ °•¢¸É¡¼—¢¸ž‹ £¨osigƒpN‘cJ€rm²†d“–Iy‘?|‰G{ŽJs}EtP€†O~}Oqo<`mCu‡BYg;D^6CW.AP!4D";J)L];H^FN\1EL8PpJr‘;azCKpn|£W…Ÿc€©d]vDVrXbƒUQb4?O)>V7X`AVe-[\*FT5K^AMp^k†MwˆH\yMSkPdo@cgQTjRYx>( ( # 02!1'2)!# #)%% !'&%%%#!#'%.-*4&/4+93!87!38(4=-<<(=<(<=$AK,@I3FB$PF+JL1RO7RJ0PQ-]O4I[8IU:LN1OP3p[8[d:hfNZw=TnQYd@cd1Xb.Xd6Te>Gg:KY9M^;_^2Yi;We@Lb;Pd;Sc4ec4\y:bd=^q`{H[r=bq8RxBnqAf†A\‚ERr?Xp@Ww@HwCab9Vvk‰NšMs­^X•Ux„qe¬Z_„IvƒAtŽSd‚G[xAˆs©Sˆ¤X¹d}“Ie¦a~˜d‚Os¯J„Bk˜Hs–Sh’Fx–Gp‡E^@n‡C{³\všKc…Hf€?Ž®Sw‰;} :|—Jw›Rok‚«SpšL{·d_‹Jrƒ9r›Y~®z|ª^sQl¨bƒ¥]¥dcˆhu¢gp™T¤¬j…Ðt—™Q¥RŸªT‘ªˆ—½R‚¡X¡Nz¬UcˆAƒ[™ªO޶s–µOoªBš·R†¥[‡ˆh¨O…œ>qŽMyœnœ½P£¥PzžD”®SvžRµéul?‡šKu S…™Q{˜Sj—A…šL{¡C{®X|­^oIp‡NާTm¤L`B|’L°»YVƒ}t‹Kš±Mt˜K`~B`Ln‹gƒ‰P|’Nl D‚šAv‰Vp˜Ol™Pt’@^˜SmNl‰Er]hŒG{šT|¨kaƒ\bEtœZ–«v™Êyޏ`¾`—´o—·h—±}•ݦŸÌi¯Ço¢Ëj–»\š¹Gv5Š‘Q˜Æc´îp­Î™§Òo€©lÄÊy¬p»ÖR¥³`Ôq‹¾†´ÐzÉ|ºÐgªã…•Â`’¡L†¡`”±Z…³z„¦‚­Æv–´v¾ã‘ŸÑ¯ÐdœÐ‚›Ì~˜Ú‡³Ø]êÿl£¹Y­Èn¤ÍUŠ­A}9z“@ƒœHˆ°b•·p¾êÀøms™XŒ¯W“·cx—J}ªNyšY`•e`m­ei‚Fm…?d€K~¡d‚©ovšZqˆ9l‡Wƒ­_Su7Ld0K`)Na?UnFuLw˜Wu£as–FgVc~Yp‰[[ƒg¨c„¦Š˜¶¥¸sy‰M\{LnˆPf•Mk7aƒNv—„ªlx£Yƒ¨u|¡z™Çr¡ÆFp‰O€‹hw–nvX}J‚’Gt„[~“m{†`V|Yn}fŒŠp^yo}xqrSuyu“Ž\£xN˜mY•{f†ƒ‹n~nœ¶`•‰ZŠPzsUvyNjyK]t?]rMrqOp~;Xi4Gb/DW+1I3X}N…NryDBZGPZ>Pwo¬Ëf«ÃP‰¦p³Ìg‘¨Yj†X_xF_rEe{5IY'=\"C^7[n@XoBj8Zm>l{D_xYq˜ez•PayAPwHYpEJT>OYHXsJ40 -$&"#!%*9&5+1/0$"#!$()(#%&$'$&)&)#,"-4&36(:$20":778 .;$.9&4;'0@!2:#AA*:F+>?)SF,ZS.ONQc7Lj7Vc.T`6Zi7]lDZsCZj=fzEgvDYzKRtE`j5cS}E_xHau2[v=js@d>S~LdnK`ƒ:[~=]x1bz<_xIEvPSa8_n?Xr?_u5lˆEfƒNWUlvO„‚Ll¥Wk‰MkˆFh•FyY¤¥RcÄŠs_ƒŠK¨T~œkt™?XŠSh{CŠtb†¡F†œR`žjX‚PgxNjGi†EyŒSg‚FtC_ˆ`|~2k„H^KzŽMŒ‘IŸ O{«dkš^…’L~©x`¡ifmk‰_`•jV}rswHW°l^{qm‡Alƒ\y‰G†Fj¨J{‡Ms«RTƒAlv:‰‰:s¡A‡™ay¨VNŠGms´I‚‘GpNx‘OƒžEv”>p[¸»v”Z}šV«OfÀb˜™‚©©O‚¤YtiŒ›DŽ—C› Y‚›u‰¬bm N”¨Sc‹™Mˆ—M©¢b|œNy¥O¦]£s…¬BebmS¶Í”²W»Z€´S‘\r˜O™J|§V€žSpšNq’S_„7tžDx¹tjµak?v–]¡Ê m›?nŒSe˜ip…ec|=g©DbD„¬Z}¸WkPˆ£N‹¡Hi“Pb†Iz“MjˆE\=]ŽFiˆQgƒ?t¢Od~Kw“Cg—Pn—Xz£g†£k‚®iŒ²gˆ¶h„³kq i|°h”³tƒ®y©n}žUp¡h{£O™¾o|¢i𯄱~ŸÆj¹Èn­ô˜™Çn¤½š˜Ènµk¨Ó`¾Ô„´Þw—Á•˜Çy£\†¦t… f~ŸošÇx»Ôj«É~“Ñs‹³€š¿b{•|…ºpŒ·i‚°j…¬†™·­‡¡x—àŠ€°t ¬j¥Ëj†³g‹²iÀØ‘¤÷‚޻І·vÂ_}ŸpžÄxs¥Sx¡Zu¡Ou›QƒªLzJm’Tw–N€Vr—Tf‚Wb…J^~W[„[b“da‡.Np/F^/Ww@RlN~±\`ˆag’[ˆ¦_’¨Gy‘Ue…N`wMlg~¥q‡«|†¶znSg‹J~SpNj”C^ƒEeXmŒR[|TkŽVlŠbs¤q„ª]¨¼Z­Rz”PoL^LjŒNn…Hj“WkŠMW7`yOj‹RvŠOla{Lq}i~‰\–†[xX“Œ`¤›s¡¨no†l®™diŠdf|OrY‹O‚ˆM~QszVt…I\p?_}]µÁ<`i5Hf\UqYq…GjŒIbw>j{M\„NbtRhƒV^†Nq„Kn”HoxCFKAO^LOdX,!4#3#/$1'/+3/2-++")"##!$!'"+/$).%,&&6$368:;=!19)M2"MM7H08=3=8$8?8=&78&6<%:;%8<%AB'DF)AH,QG+TQ/ZYA]X=bV7h]1d_1Tr?\\AJg4[^;d`3ag=Uh;ce=hp7_yEjsE_{JfjER~iMˆ†J‚¤`¶šRe»lc‰]ˆ‹;dŽf}‡Tw“cx‹?œ©HmÁX{IŒ‘Hr’N‹šU””XjÐspzLyJ—’[™Õx€€T·o—Qtmo¸z{•{„žd®¿^_¬T\}Mg‡Y:AY?B\FQkIWƒOf‘JhrFhr>amH+$3&3+:*F/!8;"?7)35!//!.3/+*)2$<%08*;#D-S@6N!28271 D5BECJ1H=-TF+MH'HR+FK5GE7JE)MF)FI-IB(>D&7B&7<(?;&DA"RH%SI'LY.NT5XY4_Z4bg=Xk@ThHYcHRs:UbE`g8bkv{Fs‘Pf‡GWN[j4vl*m‚C_vFq{DgtIyZq“HbŠNnv@i}EyxAqp=^wE\}`XoBRmZGc>Y`:cgGytHˆ}Df‰UftAWk?@p:HQ/Kc+Ol3vo?[~;rqOY€?eu>Y‡W^vMn~6f“TwŒSzœkm©pgŽ`swG@u“C{ŒIx TW‰^`l=]{La~T^TbzS“o5u™Tg‡c‚€QŸal˜V}šUÍ„F³¡‹¦\› dx²JŒc—–I‰©YƒšKn»bflk‚>wƒO}…LrŠ[i‹Nl:y“A”•G¨´[€°Vfª`R‹Wbv]—‘Yt¶P‘†Px½NnˆTzŒNw•Qo–Wt•G‚ƒTXž>nLk‘Jt‘N…‡Eš‘Pµì€ªãtj¡z‰yI€ŽVtFy‘^œŠNd¤Žov]…>m…LsŸ|¦IoŽU}ŸR‚¥CŠ•^l™Ik€HnŠFaEy_{¢f^Ul›YeŒFoˆ@¤ºTk¶Xt icŽSu˜KŽ«^xŽUYœWd‘:a‡9sGÇ]r¨b~­\b’LyŸwpŸ[|¼Yp—Sm›`‚¢_rŸHoŽKlœRy¢IˆŸbz¯lxªQ©W€›M•Äa~ºf|¬_°¾sœÌu‘¯o~®wvŸq‹°vs£V}¥]‰³o³s‘Èd“¯Š—Án‰»x‡ºs—Îw¥ËV’»by§o€°\x Vi•R}ŸG{£ds”Wt˜Mºu’É“²by¦Nz£f½Uˆ§P€«\z¡Yƒ«Wj¢BzœTk’Fk”MkHe‰Rm–[d‘K€šUqŽHg…;nJ€ªGg‡Akƒ:eŠ\ƒEa‹Ti˜Zm™YqœOpœf›®Ln‰KcŠNu”Jj”Dp‘GkŠL~¦bˆ°V©Ua•EdˆPu•O‚¤Sl‘O^€;aƒOe‹[eŠJc‹MZ…Lf‚=W€FPiAJg/Ii,B_,=`sp=n‚C^~PatAXmBgtOR€NklQb{C„xHÇ„F`¢DRhRQkAGd=†‘Nq¥6g™‚žq¶a{Ù‹t†\y©EnAi†Ks…Oˆ¢nx¤Nq5\‡6~o_O‰Lf€Br›_Œ«si˜g]‡Df„Bnœe†­GyQk£da—BkšZ~šRfžDŽ‹L‰½[w´ai¦Gp®\\“O^ƒ>_¡Ne…Lu‘Oky6›’?{­fzžZs‘Ec¡Z˜ŽL“õ^›ªNs¨mm¯Y¸`ƒ–Zƒ”Q‹›7|¿No¡IÅÐTi¾O€‚Ov›Eˆšf¼T†žGžÊl{°t†MyŸ`ŒÃ¨xÃ^gšZ›“bw•Ng‰]€“Iw–J{˜Kr¤5‚—OršKs¢Vo™\i“Zv”Xw˜_€˜E•—Z†ª]z§Ejœ@~¢Hv¬Yg“H·¾m„»^_–\@‚•Bh‘Nt•Ph”H°Q~®Xo“KrFsŽ<‰¨F|—H¢¦Rw“Ll‰tW>f|6ZwNosEV‚:Ur@Tf8Kl:]c;Uq/Rh@eo:juC[}CjvWZ{P^z@NtCl\Ck{F]…Q_rWcvEU{@^uOfyGa…CXxH\sJjyNe†MYHXrDiuI~DhŽImqDyq@q‚FhpFr}>rpKhwEz…Ud€WQl:Wd5Fe7BU"KS)Rh4Th0SgF`r7UlB]j0Xo6qg2VŠCNrCSh@]|A}„Dl¤J`…QK{RPh4\m;_ƒFd}=b‚†›Q¬DpŠGdŽEZz^rPdŽ>a‚Ey‚=xƒG~“^y_w£Ll¥Z…•7°ÿÚ¢¬Sw÷Vn˜MqÆao4ƒ…CgšRmŠ\m†Iˆ”i~°™Š4z«e‡ÐCˆªˆk˜Jeªh•xh˜If‡Gs¥]Žif®Y…W~J›Ž9†ÃE¸ÓRi¨Qu uz‹PWh§O®JlšCˆŸHgŽL|„I¬—Zi™\oF€®Fl•Oj¡d´htŒ^^‹KjŽMo¢Mj‡G‚§>r˜E{˜NoˆMzŒLs™JzœPy™ez›]g’Cj”Hp{;€«:a„9`Ap‰Km‘_[†HnEp„Ij`Z6_j@_dKcbC]f7ag8vi=b}EXi?mY:^s;^fFkg;qd:eiCepE\aAdc6j^1q[/h`5hnCX€M\jUXuKck?gpHQyKR^DUi9Mn;f[?as2otPv|@]‰JWrO^c9Wm9Zj9[n6XrATl7^w9_lEqiCk‚Db‡QNfGc_6Tm4avHUqC]nAll=csln9gŽPY†SeBh‚1hŠ8a€:Z{=f‚;€„Bb”NoƒIeŒO_ŠTt€Pn@i‚Jt‡Lf•Gp„WrE_‡Oax@U†6v€>}–HtMsšDpŒLuwD‡‚F¼¢UßÓU„åk“`{ŠZo…Xg•Mq’„‹ˆd‚§[e•aˆŒDo›Wo\s˜jgŒLp‹G˜ŒE’ÀsžÀt|ª`„§vÕ¾WwßkdJf¢?[x?^pQ]g9^€R‚„Dh‹me}E¤dmo“[k€Us{\i|WdœYsoD_ˆC^qCh“b_Žg ”2Œ×j¦¤Ty–Me’ƒ}G¬fËPv¦bt§rXF‰U†”u‡¶i˜d`a~g=x§Rr•ns…h„Ã[z‰C ±‰‘ÎWº®c‰¦fp¯YŒHœOƒ¥NÍmŒ¢Fy¬R¤I€™Rh—Cš§M¢½e|™TŒ¬sg |uš[`¬Hw5v‘4gz=quEp“Ms†ZŒ³?©[Ž”3}AušH…¢T„¡L…¶bj¯nŠ¡;‚>‰´A]§Ej‰-h†IV€AlGh|3`˜K…“B‚¥`dœUržH}¢ ž¢ms®‚hEfˆ_›@|©IpµTj–=r›?_ƒCd€Ys„9jšfžº}ƒ–Wi‘hW„^wx:†˜VŽ H€®ev¦TͬYŒÉLÿ»Tr˜_“ºx©{o‰Uo¦CkŒ>a„Gu—QvWr‡El¥_sžHƒ L—§b“´Pu¤KrœoŒ—Fq”LyŽfj°FeŒ;wEbO`‰:r‰[vNˆ—Zb†Hr‹Q[˜Jh’ba‚Co‡EhOoAaz?_‰QhIx˜>bƒ@v˜E_7‚‹Du>pDf‰Pu6Pv9[wEWƒ>^}:]…>X{K[‡KcƒD]ƒEg‰Pq¡OcB_Aa‰Nc‡HdƒJmŽC`HiˆCZ{:X}8_z?a}=Vz;m„B`5\z>d€CXv3Nh3Kj3Jp6Nt-Fe6T};g€Blw1eu:]l9kNe‹J_}Ph|BlOctAgŠW…­|w—YŒ˜G|ƒB||Axu>es8a{P˜º–ØüÒáý˜½Î•uoHh[i—Wr–Uofeˆ\v˜a…¦z™Ã¬Áᑌ£uo™Zd†KQEj‘Xp”Vz”HPoM`}C_…2T>KOgl-G`:KfHd„b€’nu‰gJ]gQcML]F`RTsGWn@cp>cq@`s>izIp€B^{QXnP`i7bc6Zx=[l:]u@=sCJb;S[0Tk1Zr]wMUlARpCmk9lƒ8^{NmuDWvLQo>Ml1U`4ahj9c‹:y–[mŠ<|ŸQt‰Bqx?z–Kw‚>a”6s™Cm‡Mo˜Qg–NNxAfŒJr£Wi˜VoQpœIi£MWt?b|8@‡£D^€AcK…šVs¡KœZ~ÃXkœZk‡\mŒJj‚Io‹EaFs¡Ad|@f‡Q„Ut™P†¥Mp˜Nˆ’O{V’QzŸR¨±’‚®KžH†ªW”ÄOj‘Es–C|¤Ez–@|Š;t‘DvœG“¥ix¤TšI‹ÃKªW”¥W„’Ds•B‡£OpIxR‰JlxB–?pƒ;dw9zzD€‰Pˆšk|Cs“Ld‡Dd‹C\}5^{F[=^€7Xy=[;s’`A\s>Z…Ha…LbM]y:QtAq<_vBWw>ZwAd†J^SX1Q`;m]:_|Cc~RqpPW{NWo@Ym=OwJGbGYbcr_V{A^nOZxCRq:QmOjc9s…=YˆMho;a{;jƒar|S^ŠHXwKQqxˆJ^‘K½”MÿÁ¶Ç†Ö„k–Ur‰]x£‰|£~lS^[„nX±¦Y±¹]À˜=¢FvŽER¢b—|7Š»]v½Kf”OŒK¾f—˜\šÃy…­@q¡VuEm‹exŠQ„ ]f‹Ee”FQ’W_~2cšLyŒOt”L„©ex½jr¥gq”by¡`Ž•`i•F¨šU ?ž—XçEƒ³P²¸]‚æUs¦m‘-ÙfdŸM‡Vcbu\˜™GtŠ=wŒ:r…GmŸHj†Qz¢T~“FX}sœQs§@[…G†“Jp’Pi‡Ye‹KÊËOm¡Pw“X…ÄX›QbŸZ“Ž8~‡7Š:e—Gt Je‰?Ry>ƒGn›B¨Âa•¨Uåþ×»ËKŸC}£Ds¤GqœP~¬px“?xžMl‡Si’=‰ºh„¯[aœL€¡rƒ¢M R{Sb“La€>gŠHh‚@]?\~n‰RtAeŠ1Z…„‘d…B`yhƒ>]„@Yy2Xw7Wy4c2Z{(Qo1`ƒ2[w7p~7d‚=w…Jm~Iq‰Jm‚DpyG}„TªŽY‰‡MoDe€B•O—©_›–f¥—Ty|T‘`ž™W“ e’¼ƒ©À’¤Å€Œ¬~wŸ_kˆ<ˆ¥(<^)'D2L#U‚1RJOgic€tii]C_…AX{NkƒUbw_ƒzV|Wdu:Kq5Ps:EkCHc;JkHa€ZiŒ]_m]‚[MoNew@ZR,cnIX`?ed;fmFdyJ_`Gdl<[q=`p@akBk]7vg:dqFdgA`d?Ze5rb?Yo7\jEQY>UW/U[2^a8V_9\aWq6Gs]…5c„KtŒIs•Go–Dp‡RxŸRqš@w”Ia@V5g†@_‰v›J~«Xt–Ma9kŠ@]Œ5`?w¤MqŒ=mƒUw˜SwŒDsŒ6}¯Js£`…;cˆ?f†5d†7d‹5g„:Z€8^~3Y}:ihUV€W`yPLfGRaKIiLBQ"jgBbcEbm@gtDatKhrFep`i@nd>…c9n‚IqtRZtB\pCfjBY|8^nPWd@Qa8g_6nj9cz=WqGXlAWh>Z\@T^2Xi=Pf4Q`9SkAzdC\}8]|Rj{@lNz†M~’Ql‡WV„RK}QIaKXl;Gs@Vj@fh2ow9m‰GeEl„KfGp|?]†QdvQtxDtHs‰N_‚J[ƒR€rTjR²“SgÍrb‰‹[>ngDk…;cŒHTƒPtiAs‹DV†[bs_kƒH[yVdwLv{Dv”H`“Rt{D~“Ic’\yy[hŒFrƒLkŒIh…ZX„U_n;i{D^‚@`~Am†?f‡GbˆSZ€H]w>RyRfr=qJ\•`RJWiEMw1Ao?g]4|6v›5“žTc´Wƒƒ@ƒ§Hw¥ShžYSNcyCw?jcn„Hh”Jm‘R[FY€Cp„O{“Ph¤U}Šp¥Nq¦XY[k{MpŒ>xDZTO|ZKpA`o1h‹CkƒG’…=£Qƒª]Œ qm¡{rŠh—·™Ÿ¹­|Í¥œk¬¦Z·»[‘Âg™¢bÛŽP¸©‚‰K‹>t¦Z¦q^”»\‹Ár„—lpªq•¤y”½”§¸gi¿]VqŸmŸ;¶r¢iexK|•‡w{\œUqÀsv}\n„[i“@xŠ]{›a¥]€¬K•bŽ˜Ph°\t’j•Zj™Hˆm8»ŸA†·x{m‡ªbs‰Xä†Kªÿx`ŒV\XMq…Rqi®¤ts‰`drRz“MhŠac—P‚›Ypœoj¢Sn—bMIg…Wxµn‰°Ok›Cp„>mŠD–8”8ŒŠFz¦P«U‰­W«Ís~¶c¬W|™UjxQuŸDt¤`k¦O‘’Yt—z–Q}¼¦ržhl¤Ov¡Pn¢ac…=n{B|ŒF¦nŒŸ@qšPk‡FT‰Azz:p†Gk˜Hw}=|Ž;{“H‚’H|¢Qt’`•ňdŒ@]‡Ekˆ>x„JrˆJ_–BwˆLŽ«Yƒ¬Kœ«PŒ·`’™[€†U‡‹P]}Tc†c|‹VyˆC\ŽGn_KyFa„?mŒ?v¤X¥Uˆ£Z_‡F]{Pt¨Km—HhG±gpžFgžLc…K…’OtƒPz”FxŸRz“IwHcIržGw•?v8Uy;k~;f˜?^…9e‡?y”NiŽDn Gp°A€¨Wd˜RsW|•nŒ3q—Da{=`‰Cc˜G`…He‚Wd–K[ƒ?t•LW”7k†>¹O{­V~°L¢ZjšO‚™\hXhŠOgCi”IŒ©Uj‚IbŽLoKZƒO_’@ZˆAu\ˆ½Si TqV`ƒHjBhZi›h^ˆ^zc½ìu¤ËX¹Ny«Ux¢[‹¹v§ÄiÈ[§Hk—^q‘c޲RY}Mc”[©bw“YršWo’\âõŽúÿ‰çÿ¥Äï ÿÿêËõ°±Ù¤n”Ÿtµ½y”£tޤ`t˜]‚¦d}’aœžcÁžV–šDj‚L©›]“›a±¶‘™¤H—‡YŸŽO‘€^³•_¤”VˆŠN|Z€VzBl‡MŠ•S†Ÿ_¼»b—›v¥¥m¤\s‡zr~k´«[Ç¡l»Ú¤ÛÿºçÿªÝÿ£×ü‹¶Íz“»ws”w˜ZL]0;U"Ea!Ha'=V(@[7KdDWpDW]AV_?bpJ_{VXtUg6Xv@]…Rb‡Eh|Kk|Nd~Piw2rYAsiDY„LUwTXmR\hJYm?]nAXnDYjAkeJyv=j‹PnmWYuJfvPnAoŒI\ˆYMtCXfEh`9mt2d€K\[`hFdr@]gAVl@OiALm1Rf>Pl9e`;V„2X~TUwFZpMkuLj†MlŠU_|YauVSyA_f?Zz;byFix9i‡Df€Of}X•…T}°PgŸgVU^nOuqGgNo†]S‰UWw`ziCSŸOe„d„…VgŸ…OƒLkj@Zƒ6V}RXyLesFq€B`‚]osTk‚GU‡VooPi;a„Xg‡Xd…MwŠH€—O•šUv­bhš\Y…Rz{U]•Lk‚IiŽGr’If‘_x‹L€“P}Ÿ[Q”RWpL‚}?\¤HbƒZcŠV\…NXuAJx8`gE`z5`„HuŒT…›_d®kkŠ[w’Hh¤{`”l\…SX€Cqv5g–N`†Qa‡Q~Wi¢ZQ„PetIgDh†\QŒQZlKLxbVqgxpF‡…4jTp‡Mc‡L^zAmn6ª’Ao«a¬“PÒkwšƒiœ[_YqzSuŽdv–|j™b_ƒH\yHYypW‡zjmkŠp…e›¥_¯…g‚¿f½™MžÅU®®ki±s\†Yit9ô™X˜ÿx¨ny–E’p‹Àh”X®»No_¯ŒEtÃHx‹bk›bf†J‘x:¢„FZ MˆjOv¡Lo“sŠšU±Òv‡­dn•X—žDp†^‚“C™«mx¸Šf„U…’VžD¬§F»Ø³™Ã–ƒ˜;qK{ˆC‹§P’ŽQp‰P‚¤FZ ^v‡Ax¦H‡œJ†•Ia„DX†=bn(h}?sŒU_’bwPm–B‘ƒH £]¯MzœN¡L‰¨S‡£K‘SoZuƒCk“EeƒDvŸNg†D…K¤bn‡@o TcK‚®C„œ9`°@yz?¥Uo‚8„—8j£:x‹G…–IpZ€¥b\™uz†Fw¦Ge‹GvLIp×j}›_…™Oˆ¦Zn˜ar©J‡ƒ9…8”Yma‚‹TgBh|@wy;¤?lŒG‚Ctža ¬N”«X…¼X~Ar³Zj”F†A[‰;p‚w‹Ob“_}}P_Ea…6h‹;^’:n†Oz‚XnšDlŽC_ˆ?o›dsœM¯§Gv;•°~ÅL¡?…¥JaL\‚Nƒ¦H«Z‰¦Dx¨]†´Md’Jkž?SuKs£z²ˆu«l}Ÿ^zž_­k‡¯w¦Ãpn©Tx ;ˆœe˜Åmqš=hˆOx›cƒšo ½eo’a¬®±Æ·«|t¥€”º¶°Ç©ž½b¬Âk‚¢nwžktŠ\p–TfŠCmWe‡T”žb¤¤bm£LpR©¯idƒ¢ŽŒ¡Z½¡m•¢i² qÀ©o¥Ÿe¸›[¹©Q=fw=nˆL…˜\v•Rz’Hu“F}›NgGvD{’?tBc};`C~¦ëÿ¶äèLqEx“Fi‚N‚˜Iu?u”Dv„D–>hƒAx„>Hl‚5wˆE‚•EƒŽRvB^z=x“Nƒ_|Ÿ‹­Çw–¦^~rVMeFl|Oy‡nµªw±¼ƒ‰ ¢•²¡€¢‹„¯°x…¸n|ŸahxZRfE>U+:N7J*:R=GgOm‚t’Ÿ|¡u†‹^g{iq€XWpT[qMj†c—\bqTcpYg‹on~UWpOOmSVl@>P?LnI]w[d„Wj‚`|Ÿc¡e}ŒCc]CyhAcŒGY€eQdPM_AP^=hbC\s=YtIgiJfw=e‡XegTe~G_yMh~JkxKgRVzQQdB\i2[e4awKTsQKiNng?oy=VƒEWdIOh8QjBJj=PZ8Jk2WgONd[s?luF~~C|£PO¤gjiNbƒ:]xSjCa‹bnwH‰–N‡®`rª~e—adˆRt‰FxšJ\’Y_vQ\„PT„hlzHz‹Rpžh]‹m\~[\~7WMU‡UbuJ[ˆG`{HRs?rm6eEm…LgŠN˜‡R‘´iU {`zA[ƒLhŒTcŒR`DS‡@fp@S“DWsFgz9hRQŠMLnJXjA`|Gh{Hd{3gƒ>h€=o€D›zKl¢XrxGkI“ŒM…ˆIx’Cq†jŠGuš~ƒ™ob¦Nk‚Fc‰G~‰NuŸil•Kk‹HWx9TnZˆT€uJ\“Ce|WgkGk€B[‚QczL€rEnLX|KNdLLf8Od5Rl?JlCUgFel8g{8SˆOSoLQd:Sr@JeAP_5Hc4Q]8Sa/P_=HZ0KX5Qb;Mel•Tp|Xd“ha}.}‹8|«_‹Ÿ;r›P™·Tq§ai¢IhœUbN^…Cwz8iŠNªŒL»_Y—\cŽ?ežJrRnŸPkŸV\7b|[[hŒOd@w’YhOg‘4pŒBbu6p“Ji‹Ekª8~„6zŠFmv8¬Jk‹JoW—¿s†¥\½]‰ª\i§IŽ¢FÖcd˜qr‹dhŸt¤›SÑÿÕ…ÈR^•g~¬Y†‘ZxµLkŒBœ^|¬i{•Uh®Qo“H_’¤M ”š—Ǫa³Kp†J]”;uŠCc‡2f¤;mTd…J}—Kt–S§N“§O­¦@y¹PožEp Cc†Fa±=lˆJz§GzŽH{˜FmQbŽ9d€Eu‹N€C_„>XtFWŒ?t…GYŽ1V‡=Pz4m‚7f˜9ƒ¢8]”4X€>bx5aƒBm›FMx2[JKq.…—DcƒHZ‰A]„;}˜On„JgžGjƒ<‹¦6‘µYj“Rkœ=s=m ?Z€7Uw3i‚Ah†FiŒedŽ>]ˆ?±¼lq¦8Z‰?Vw7hƒ2n‘Kdt9kV‹¾\|¢>pŸjr¬X“§a¯Ô{®×_|¤B]E}¡]fŒ>^Š?u Bo‹Pf”pk›h‡˜R›½S…©ƒp–@Nw_„8U|8]ˆ?S|Ai‘A\€>S{Em’He‡I^‚j~9i‰7f}.DR%@K5=V3+?E%;W0QkB[J>MH<`V\uEmyC[uPYqB]o8_pRŠ¢ev…JQiLTe=>WZiF\h@ekEqwBjˆL`ŒZmzWR„I[l]hgBV|DVqY^jGƒiBlx9Rn>HbJAab`8Xg2Oc:Le=O`8Wg=iw<_|PosYb†JeuWYxOLrFRm2byBPqP[e9Mr;WhBbi9zv:‡Fo™N…iO ^[t`Ty?frHR‚9]pG^vFgg?a=pWtK]†S^{MSƒUZpRyx8]”_TwSt}Ga˜GT‰[ewWJƒQGiWSe;\k?TtJ_tQX{S\pCjpA[†:WuDUKouR[PP}ATx.[p5g‚:bŠAZ‚QRk;”u;’µ[^¨u}L_Š4C‚MmdIQŽH:vMtY/jŽ8J‘iViabt;U€LOqPhuˆi>—ªs€m¨L‡rUX—T­j.†¥UnuTrr;š‹Bm“El9f£P„~Bq£Wgz¿l†°`f™fv†G\|7RŒ0cp^ƒAk—SV†9o†C¬¸emˆK{’UI°Huºe†À_XxDW€1`‚DzIp‹HdŒMl¦ni`rˆNi“Fh•hi“hÅ~бe¤ºLz“klš?n‡;f‘FtRgŒLhšMk‹zc‘acPLyBVy4l†Cbˆ]U‰JS}CvŽ5Ee:Nq@Ky>s‰M‹ My–MX}2Md6s?sŠ?qŠU]v?XbLy„[œFWj+V]?HZLMg8ˆŠc€‰|lˆZc…S™YlA]…LU~@X|4X~CLq7R~A[~4T}6hˆCfA\8k‚Jj‡KnŒXs•Tr‰Km„DdD_ƒVob„¤O‡¢_‰¢Yn•Eq<_v6e;–Mv‡J}™YvRa~IqŠK~ ]Ÿ»y’šIq‰Dt‰Q”_¥¸w™¨t¡¶k†©VƒŽUm]€¦pŒ¨Ss’]}—QwŽR‡¦l¦zÁ´_•‹_ª¶\i€t•o°£ÝüÙÁæu©žn’Ÿr†§™ ½¼ÌèÃʵ‡„Žbw•_]WpšU¡³S‘¢h¤Ç‚ëÿöüf¢©9Vc2TX&CM!3E'Pk;bt>f‚)KhI^yOwƒDQfIUvH…’ExœTiŽ]\qL_uK\o;Z^1=RF\oLVrDWs/Lb1RnC[Ot”DUcMSf?ab@]h:TuEOkAUgC\mAd{OZ‚PUxSMmST`OZb:Ej:H]PUdAa_=Yo5EjARb9Ii7Ha4Ea1RV,Oi4Uk@^j9Xr@YjWbd>qi0]‚:^tOSjBk`A_€CY9OZ3Sf:ek9ZtF[kR`vMXoS[jJSj@LaRqCZt6[zMk|J_—@H‡N9`TMR@Og4BmB5Y5]R,ZxAY€H_kHQ{:kiDa…6f~EN„A_mGy|@d—LPŠJ\|?`Fa‰BmNaŠ?n†6g’If†e]ŠGo€E`Get0O‡D_uBg*Mš=[mUKt6P_*\qGW}HL}2Ts=`vVW‚AJrJPj8ooKl•Siikšmq˜J€•E‡«[{£bqœ=—Yr³j“ŽRœ®hÂ…™¥Zz£pq—ep’Ul”A[M~„SuG˜¡Pa›M’‡P„®^h•XrŽTyˆNu™PxŸB|;©Àiƒ®su›Bœ˜7Ÿ²G¤Ùj‹­]¢¢V¬¨U~©O¥ŽH­Qr¨mÁ‘H–ÛToŸrYVro\}•`kš`y‰a†™a‘¡[†Çn—ŽÒÇe¶UxšVuj=„y>‰«‡“‚_š‰d§Ž_·Üb‚´g¤‹Iv¹_ÍŠ`ÈÛd§ÅZ¡‡Q—Bÿ¼X³Ø`š´^ª£P›´ÇLw¬T—ShŠ8q†@hƒoˆ9f”P|W•R}œUrQb—@…„CiPrŠ4€ P{Ã_f™Krš7}—OhC{§:“Êb\ƒ7K‡Jn”IaƒBhƒ_eD]‡9r›>Z‘5d‘Ko“TbŠJx Ar˜K®É„¶ãUfˆ_€›=k†F“Il‚>s;v–<€¡@‰§F^{Ya“O’@hLÃ~u‰Sr›T}•Eh9¬>a€GW};l>]ŒA‡ŸE}•T~˜@Š«=gKl`Œ˜lz©‚€§Z…¦Hw˜VV{8nŽ]}–BdŽCU‰Mg’Cs‘Bq ?j…O]yD[}3`8Nm6j‹Y[‡(St*WvVcyfbx_[|KHk>Ym6{V¢¬eÞèb–½C^{FV^>WgJm.‡¦Cn;Mm@a‚9`Bi‰JdŽJoLv’E_€=Zz;PrJ]NeyUz•E{“Bd€[uœq‹¥a]u>_pBOtHYkIV€EWlKZlDRxBUnCYlGiqM_}G`yPaoBdc:N~BLhCW]9Tk8QdCVc?Nq9CnG@d7RV-Nl/Id5Mc=^^=Kd>`\@Zl7UlDPfIOdFec8V{9DwVMW>Me2PiANiJYdKKXe;f:s”@u’Ki‘IU‹M`vDbwEG„Y>e[^p9SxA[m:a|>TyBQoEPqCod7U„=lv_rŠEf”K[ŠDsˆPq›Ld“J—‚If»Q^‹N\L[€OVsGN„Dkp8q‰3]”M—}6`Ÿ>XGrp<ˆ—JRJ\p7ntm”I†V€·`]ŽWm6}˜gv¤ls©t|¨q šhnÈjj‘\s„K–™E{¸Vwމ¬Jˆ¹wn±Q€˜E´mq®u†”\œ²vÁl¨k‚X{˜\†¼{­ U‰°t†UÈ¢A“Õ°½¥[¥Âo °Ož½N¢Â^“ÖI¡¦O‘¥_Œ¯uŠR´›l ÕˆËÙŒ•Ég˜£L¡˜KˆŸTŒ—P—Œ\¦et‘b¢‘J€Ço”›Fפ‚¢Üžµ•e“ÍP«½rŠÑ¯v‚n|›a»»Š¬Äz¬Z›RX]˜=aªGd|5À†=~ña€Bn•\Œ¦Yp’?†–M«Jw®P£Ž8”œD…¸^y˜HZ˜Da~5s|^–žWPmÝZ……F~®I}‚=e–H‡²4r¥C‚§ZvžW„—^m«BrŒ@iœT}•Me Hz‘Di‡Vh†R|‡AŸdna•ƒ_«§{ˆž|žškºÇcl¬K•¤s‚Àfm¬G`‡Br›Ge‰GvƒHƒ“I|‘Oƒ¸•q´n€UaŒ6gˆLW`X‚C†ŒMw¹deŽ5j8g‹Mpanƒ_eC‘±H}¸UpŒCd‚3nŒOf/“7€”:n˜M|¡>z–;x±MŽqõÿ׺Ø~j¤Oe£Qu©Kmˆ:d{m—N•Ur™Dy¬Qq™@v®Yn“K™b…Ïzy¥Q~¢o^‡Ax¢\‘¦Fe†@e‚P}ƒ[ªjr–@Ž‘9”žYxžBi¡Kt¡LŒ¾W¥½|޹;m’Xj¡Go”6œN†¤BˆªOvŸQˆž]|¨_`—K}¹LgŒ`n˜Ud–^r›WgOl‡^s9_k8gkQ~…•ËóÓïÿšn‡c]zLªcˆ£Nvš\{“Af…Bt–U•§p‹±b£b}—Qy‡[rƒI‹‡P ¤aª´XrŒO•^¯Ð{Àé‹©Ìn Âƒ˜±‚¢¯l‘›ss—^–½€²Ï’ÃóÄ×ÿ›°Ô|Ÿ±Zpš\y’\ZhFZk9m}F‚Ž^w©“™É”¿m‹®™³Ô±¡¿¡¯z’»X\j3IW/B[06MDHfO]qWv–iˆ§]’±Zˆ¥Wƒ£JiƒLo‰T]kCft>o\C[ZNjj:Vf:dsDrˆMd‹`bTevNSMdkJlfAL~:XaHSh?PkAMpFVb8[_+Ru0Lm@L`g5SJ8H_2KU>@W>IN8l^0sy=_†UVpIMo6c\<_p?vmHi‡@^UZpLPn@TWB`g7nwFihG\ŠH^wC\f;gv=Z~DNlJKp8Ti0Ns8RiBKq:doAd{?N€@XoS_z>a‚SKuDUkRUzG_s7gwH^w=m~;ŒIo¥ep˜]w„YU”XAtRCaHPV ªHh­diS_y@‡o7Ž™Fp²Wd†Khu?Yv:\vFwˆG„ad¦McŽbW€7\tBq€@j–[jŒRb†MV{;ns9W†:f|5{‚8q¡Wp”C^yZ¢}B€·_X¨hZya_u<^‰LS{NOyXMk?rq4]Š1R:vm7|¥Oƒ¤;l’[t…L\˜mb‘It•Z‚™Pg§fw„;~‘Hh¬qh€JfƒE{Lš›oƒÆq‘´fu¸Utˆ_™¨UŠ´b{§P‚”Xv±A‡œ^ˆžcw­phŠD‹‘X§qƒ›I‘¬O±vg•w¡•]œ¢d‹Ûf”–y¹Ázh¶i“z[†²‰¡”US¯smif¡j«¼m›±h‡¦] ˜dRª_†NBŒ¢KŸbŠšcŠ›„Œ½Z¡™_†Ç^xJœF޽w†—Yt\Œ€k{ŠRž¦T‚ [‘Ðs¶—t‚ár£³‹}¢C±’@ŒÉ_²~pt”qr…Wq¬N{¢Pm£nƒ3¢‡MŒ¥Ÿ•›LyO˜¢@n—B‚šA}“X­€Œ£d~˜hz¬Z¤I¢‰Bm€0j7x“Cx±zh¾wE„’H{–ŠL‚<€Š@†¼~”£YŸ³ps§„•£kŠŸCg„Hv‘\„žZpŒ_c†^ŽL‡¼Po€Dhix›\‚ˆH‡žN{–Z˜Rn§Er”SvœMbGc‡CfˆMkG`†F…JµÒ˜¶ÒqÆó]ÁÛi¡Ð`qªG†ªc‘·d‡¤Qs˜E…ŸV¡Ñ›ˆÊYc•AUi@‹­f`zAiŠLsƒLh}@Wg:brSd…†yˆw}™Ar›$8E-C7aydn•+C](Qf3o‰;l†Ag{Jy”]p†SQm3]u3MtAƒ˜Ie‹St™b‚¥>h†[~›Om†LpŒK…˜Gy“MmŒ@cMw˜l„=o†QžO˜½e‰¥T˜NiŠIZ:_†HjŠDW‚KtŽOy–JcŠd¦v¬o®P~šPpŒJ„¬^ƒ•[qO„›\w–JjIsŽ]— [²xµk¬Uƒªeƒ«¢Þÿ„y¦k„«p•°o•¥YuJtœ\«ƒ’®xˆ¶’¥Ê–‰¶{‡¤Rj“b©Óh¸Íd¿Ãe¥¹n±³Pˆ”‘•Áš¤Ä‹³Ý¯×õ¨¶ktf¡`oŒQ~–Hey;]m0BT9:UMPidg…jZ‚f‚ª[e‹N`wH\~_}ˆW”•]‚‚BO`PivZŒ£?h}Qjˆs{œ€‚‘~‹šo…k|Ÿge…J[…T[pTQiMed?ctA\gCYrOioLe„<[‹Ke‚Ra€UO…SWpXWfFqjAq}@T…NXjFIjmqCm‰G_ˆV]{JM€;Re:Kf6Ri5lm7b†3O~TXmJWk;OrHcaHgqCMMkpFv„?VC[wDp~Bcœ[Q…e]xI`zNl…Sl…:M„=]c7Tu9\p5f{~¦Lu§N™`]»caWO3Kb9ga2o„?pŠJt‘H{’NvTu•L‡‘Ht˜h€šM”œSf¬Q¢ˆ>†ÈˆlŸ…RˆXfr3W‚LL{AWl6Zr5Yv6XqGe@fšC—L‡¸S€¥haœVa…@r€m›T“[tšPa„‚°C‹˜<™>g¡D›–^»à¹Àm€.p­Q§±=–Ävƒž¿Z–°rg?s™Wi­Y’šI–Ä„n³S€‰a¯U™©HŽšQ·âmy‚LdžIa:€ˆCv—L]‚=[ƒ0Vu.r‘Sm”>b‘EbR‰‰H|Ÿd_‚¢ÇXŽÄdpŽBilƒ?W•YjqTx†Cq W|ŽSpŒF]“\p{ZlŒI|D¸”S‡×O`°whzRY?Tl:kq@a6c‚EwGƒUX¯jP}b_u;y=užkV…VmgU~{>V?Šznp©iyœm`’o`|Tm|0X€Aep,{7}“Qr’NX€B„ˆT‹”H†¡Tz¯ylW€€Yt˜PNS,qADM>Yj5s|0]ŸLRoIur2m’@q˜:hŠ>Rz:f}E€”<©Ww£\^˜\gƒGpŽ@[†Bn}@i‚>‡D]™p}zI€£EhŸVl†F¹…B¶ÐplÇb‘Fr¤T~–_uYx˜Z‘LŒ®g‰U–O˜¨\¥²‡¢«UtÄb}šW”¡J§¿Kœ¦iº¥cjÑN¥xPªc·›PTªkMd-kMD®‡$¥¬z“ŸP{ÃH›f°­‡–Õnž®`Îm~ŠDƒˆ/Á¯VŽÓ‹˜µJФKt›?“¨W‰ªm€›]µŒYŸÅf‡¤Zž OŒš`…ÌŠ”`œr¡U‚¬_©§AtÌdŠ}9j˜…|’Pl†HY†QaˆQd“D’W´u±™]ŸÚˆÞ¶†`³ppx>eœ;†uD…‰mŸŽ;pžY†™Wœ¤dlšw’’Ay¤U†’hé”M¨éJ€ÀX™³R…©7\Ÿ]rP_©mfƒ=g„OS†XdAy‡9™šWnÏ€i¼Pš^~—dl˜B™žbi¼k†ƒBš¾¦}šPx¯\¦©M ­Ls¯G™¶Bb¦7wŽGœ°VœÃVaÅFVzFqB ¹ey³VpšYs¢?p¢Gn†If•Na™Ošº`sµ@‚«Y}’K‰ÅYxž‡ŠyI­žƒ£Õv£wj–[}™e‰®I‘ÛtÅežµW‹Þšn²k{ŸOÚÿdaÁGªQŠšhtˆKb“R|”Ešk—¬mu¨”•£H|¸J€ Ay—RŸ£s©¼_Vž@Yr*“¥H—H–Hl„:”µPƒªNz«`lˆ=a{KŠ¢V„´Jm‘F}OŒ°Q{£X¢gl…_]ŒD`?o–=P~,}ŠV}škn¥`Vˆ9Š´W¦Qx—DyQ‡ŒQ’¬a”®YƒŸQf˜Z‡’XlM™`‡Èn‚º¢³kkœEs‰K~ŽYk†Iq¦Bz’Er©Py›QޱM” dnˆYt’R|œJv¤XÅjo—cVr–jn‹Djƒ]„­Qy«gpŒ`d‹=a=_ˆ;g‡FgŒF‚–\†¹ff`qZpžWf“@k‚Dj”Dd‚Em’i‚®fz¦Kb€D‡žYt¥AsŠOp4k€Wd‹2X-O}9t„Nnˆ]^gcsˆR‚ŸN¥·gš¶gm„I|?m‡Nz›bZu5EYI_„][ŽMY|?bNv“_„¤MzXc…@U}D]€VŒ§^z JYƒ?eˆAjR‚™Ww’gƒ¡^r…Q[}Ib‚WyšYnŽRcŒ]e…ScˆJmŽZ|›Uj‰P²Wp‹[’¯{³Ï€¹áx¤ÆO€£Su˜EhŽIi“JxŸYj“Naf†¸]b‰=bƒOr£f©o´jwRfcÄ^ŸZ¥S†¤N~™O{›VŒ­b—«_Ÿ«e‰¶ˆ…¦kcrdf‚eu˜|žgc~m“´jˆ—_h…QpŽPo¢™‘ϯ¸àyoƒN[w>G`4Qo3Xz7WpANa6XvYˆ­av™TtŒZ’¯€œÃ…•ÂŒ€œ†bˆw]xdYuLVuMRpgsŒtu“op‘„¡Ä|†žjEaAC^ˆ–Mu cX”kk|al‡J|ŠWhœe^ˆa^{SgpTOt>dkJNnMQrLVcewGRsB_e=`t4bj:osE˜zJfÃ]um`z?jcBo=t…Ke“MŽ€L¯­Pƒ­[z g‚–Y–bv`d“XtyJ—Ue–^[‡iguSlyJl†Rq‚TdŽPgIq‰QX‡YftJm~<]…9_SfxIl~M]„Ge{NU€=Yw=[q1Vw9RuN\kVpwBkŒQb“WU†Y]sU`€>fCw{B¸šVuÝcY¢‡Z{LfuGX{„˜V|¢Lœ²L[Œ2j|~w—FpƒO‘¯V‚¸i»m¸|k’JqUyŠWWoGnŽ=Me6YsAt•Ak‚>^~HzŠk{fn‡R]{6Vx<_xoCk—V„¥d‰«i{›Kv’e}¢dgˆP~—U¨c˜ÆY¥Ðm¹ÚjŸ¼j„¢iš²Y€¤A]}J}•W’°e{“Ug‚n€¢u{‘I];^zD__r’„~²oiŠ7^‚2`€6x•H‹­Dcy8A_6W~Rp˜X_{ITyc„½†¨Ì‡¯sŠŸXFZK:X9@d=euDZjSa~\_„b{Ÿx¿s”¨[VjDRf7cl9i{5`ŠBe‡\l‰ck™kn‰dJIdk`fWcˆb]vReoKcrHa{TVlFXhE`d5RtU€`X_5Vqd¢Qu‡h€B‰‹Ot¦C{—Gy™^f›Zd‚^\‚w‡Iy:h†D¼dá´¿ŸÎÿªN˜o^„\m–n]˜]]ƒ_„²aZ™px’2–7W…=}˜>‚›Kež`—~1i‘i†¢M{´l¥¤[³ãmx¬Mc˜q…Wk¡@“ vŸ­wz˜E”¨=¢Äz¿œŽ•µf†ÇxdŽ^¨¾­‡¿‰~´goŒJgHŸ¡w€¡VrŽMŒ¯x—Í{†²Q‡¥W{Q}¢R{ž@m˜AŠAm¬NiŠAp„Co–R|ÌZ…ºh{±Dp…E} `~Âh‘ Y°qq¬|z—DržQw¥O‹˜WŽ©v´ju¥]r‡PŽSŸÉnf”L–bw¥Xp‘Rˆ™Hr¤Mo@¥yŽÄqkˆ\ˆ§dx²Zg…[mFmŒCo–L‚h‚šWy­BnDeFeƒHt•MPx7`R]}4^u4iƒPa‰9t”AV|=j‹@w›PhX„ªXmœNf‘Vv—fx˜Js•Fxl§Âˆs¥ca„5cwPn…OmYwš\y¡Gk”K’œ_j‹^‹°]T|H_rJzŸHn‡eCi—U|Ÿk~«jxš[\‚]n˜T„¥Ir”Ivžl«ÜŒÇï‡Æá‚ªÆd‘µhœ¾`Š©Ds˜UŒ¦j¯ZdƒD`tRIfUUr@o•D}—8`v>_Ve‰Q[…;oFp›O}©]x¤L\{9Uo6cGgŽG]}Io_Œ·ƒ“¹puž^hŠ?Je9gŒ=ZtKWkH[nLRsPuŽ[~›`t”n|—eQwSLeAMl=_p@o{Dd‡Mt‰U–\d aN‘e_oYcl;j{HmtIXyRslJw†Ft|EoJmgI\rEemH^m9jvJ^rGTtL]b@ef6swElG“}J]¥VW‰}TnLycH‡@kšN{‹]–‰S† ]sˆ`ayd[wLfS‰“[•–eŠœof™sgˆku€Yd“Rg}QZM_uIpxHr}Lb‹Vd„Uz~Am E`]TyQLp?Wj:bm0‡}?c§GRx€kd:{l;sPYYexM’‚;lªnQ“ŠdoLr‚=q‡SZ•X€z[}žY„¡qh•i‰Kr“Z^„ckB™P€½dx¬vo‘ZsˆVg€@lMwz2W€HYnC]m8dzNc{=v…Dk:_Œ:nˆ0YIj|iktRw{<`†NTƒSZf?Š]TmPH…E`kA\8VvKœ}%‹«Fq¢\imu‘g^`q}2½ Nâch£iÕb»ñtˆ¸o{¨D|o“M‰»I„µ^s­jf—efsO~ƒQŽJ™B~¤M}žYm¬_††ChŽ[…‡ImšB‘5—ÐMÆ™ƒ©ˆ‡¨\y©z•œ„‰ªdqžJnqYA•UrW7k‹pˆ9¡Jz¯h” k±°eªÏ…ŒÃƒŽ¬c§NŸ½‚œ®s«¨€²ÂgÀå°ŒãO~žR—K{l¬”L¤ËvŸ¼“¡ÉªüÍóÿ§”ÿ¬·Âd©àº™Õ{‹°b~³d–ªQƒ¤„w¦VŸ›BuÇws¥HaŽEyŸQ}‰OʹSôÿó‘ÿ»a¦^d†9°¢Q|º_‚ˆUŽ Qoµb•’Qn¡Xj“LŸ‘C|Ñ\i‡`m›Sn‘]z˜bŠ|Uœ¼t‡ƒwh¹O€‹PŸ_€šGZ™HqCŸ‡JÉTaŸÄk|?ÌÔ¡k¼„;xŽ?i‘;a†8ƒ›?q¯h˜¬[_MXv-|ŸAy„D„V‚®P|—_}ˆSv‘Qx«Q¥z¿¢ê¾s :dŸ‚¯V‡ŸXÜìk“¾grQ‚ ]ž¼jªãqv“@zKyZyMi‘Dp“\oŒJt `eTx¢at›JiGk“UvŠL[z3f@fEh„K…³M|šE—¡]¢=_ƒFs”J~›RršP„ŸLn£Ow¦Qk”Qu”a‚œgfˆ`QcGt†D€Nx“Ts‘Xs’Mh4T…M®¿aOtGJp4\mq‹AnˆDe~AQqTk—`·o}©h‹ªQ]~=^…V„¦[_vKOkBLoEToa„blŒLhxPlZWrNak7Yu6Uw9jq?s€Ep‘[q’ce“jT‹kPrZepguRnlCfqFbhBjh5e{EdM„zUw‘MT‹e\iR…o@ž•H`©be…ty‚NtŠ^{‡_`„XVoQe\>foGv}b|~an“rl^sNqM^‚[Wy^MsLLh=O`@YsPsmPz…@}’\”k}Ÿ_n™T[„KipBm|;{ŒNb–cctKSj7QjUgrPl”Mn‡Ai€PcŒpe„Psy>‰Kq´`{ŽY~”B˜d{¬Zv‰Wx†Sf—T]DVz;]Ws~ikŽQv’Lg9zƒPp—@‘Zn“KsxJt‹Bw“>U—Zfx6x‚Tg‘He€PhnNty@W‹DtuM…‹P{‰H¨…Bo¹Y[[x~2UI^u:Sv,MgGbna]ˆE|rP~Yg¨7y„Mx¢~w’eÈ—@ËêˆÝª~Ÿqv«]k™^v‘Y]–\fx`j„H|~C´¢G©Öb‚»iv¬_zb|ž[‡U}¶ln’HY~rhrA”—e›ºis´vt–YkŸ[‘šT–ŸYž´€r°‚{=Œ™4¼Z¿¯S¨×sn´pž…Oœ·[›µc·w£’`޲eŽŸ[’i| P‡­mâ¨pðÿ˜îÿ›Œïw¡ºVޝ`Ú§fßÿ ‰ù¡ë¡žÿÇÿפ¿ÿ¨õLj¿‰~µYƒ¦Pu»_„”_ËÈW€õM‚§g“ Pˆ±J›½:©È\†ÒNÆø†wÔ‹x¢o§¿H£ª_z¶}·ºCqØ[c…O››Jxµd˜ŸC‡ÉU]”ƒŽIŽºI…¥M„­I¹Mu½}¬±pŸÙˆ|©O`¢sZ|Dm‰LnšLwN³ujLr<—F‰à’›¥Wƒ¡a‚ÃrqŸgrŸV†«E‹®_m”Ev•W„Édwƒ^˜HŒ¦^›ªV‹›^ޤW”“d»?spH‚§„q‘Ep‘I“¨C¦ºq{´z†±iŠÏqN‰Ck{g‡C_€7_ŠXk—Mg…ErŽ[‰–Tg’8n‘Yc~?vŒMVxao•^m—lqŒ[r@q‘DavPvšJx–Mа^iEf“LiC‘ViŒKmD™”Uo’HtZm‡WTvOœ@k‚TŒ°e©>du+UfK”Ws…S|š?j‚ATsFg`iŒNrŽNuSf†fb6Vo4i‚Hu’T^€FlŽCbDgŠOeViLv”Qbƒ?r–GmŒZk‘1Y€2Xƒ5[F…›R{T~žJlLa{Ezša Wj†Ug‡Ju[t•NeDj‡LmŒd…¨`kˆEnU]€F`€Dh‹L^ƒLOvGlœ_v¢K•:Z~Zj”Wm™S‚£UxŸ`q˜r‘«pƒ—dƒ³†¥Î†ˆ¡i‘º¬Õp È`’°U¥¼kš]‹”\­u¯Ø{ŽÀg“²\‹ªSŒ¦Kp4[y@iKn˜Fh‰R‘¤O„¢M|”?y’N‰®]ƒ³i„¶wÇók•¬L}¬eŒ°Xcw;SrF[wLvbz‘Zc|JaqRewJgxMwB‘ƒAp˜P`Ž`diTmxXNŠhRdYPiVCdR\aB`h5nn?^ŠK_}UurQr€L‰ƒM†V‹UˆRiŸ]t{\jxDkyG^tGƒxDf“DhYiO~wD^]V|]tg?d‡BT†i[f`Tj:exCŽxQ‚Yw‹dguLgsBxvJ„Jf¯erdiŽJR„PYkVWvO\kFPh=ŸxAµÊPfÎUx…K`‰FUŠI‚pC ŸDhÖk¢}]ažO±„CÎ×`«ÿ|¹Ï·‘ÔŒ†¹U†¤l¤\…¦R¥b{šU‚V¤¨L“Æ|¬˜v¥a¦J°¶N¤³bˆÈ{ehqFˆ>¦®7³¸xܦt†Wk‡\¤9r·H…S§¤pš´iš´Ii¬X†’e±¨u˜³~‘‡Lž•\¶°`¦Ÿoνb°¦S¯‹X˜œU³¨b‰žX ™TÆÚuÕãÂÔê»—ÿwѺh¹ûu¯²Â¦Û¯±²S‹À“a c¹¦˜ŸÛ©yÉ­¨‡3½H—OÓ²Géÿ~ˆÿîs‹\‚ŠD˜½^Ьuu²dm¤mq†D‰¬d}›J}M‚u¢—S“Æoµ¤q—FkžXo~asž\o°zsƒK‰?pºjswQ}—\v¥hq‰`uŸR£Ä’zœkqŽMjŠ1l¢=‘C›¥Gm²Y†™1dD^ˆ@‡‰}­ÖX…¯ivŸi‚žYŠ‹F€”^“š€xŒUŒ”j߯Zª@”¼]u›P©ƒPæÞ”Ýk“§a‘¼p”Š>€Ÿ]mÒj}¥Y‰›cˆ´bœ—OƒÆg¬¼jp†Dcs3a},ˆ¤Gt”lz‘Nmžmƒ€L›ÂŠŒZ”SªÿŸÖ¨ÆÈû‹zÁiñÙÀÈÿv—Æ]y¾{X‰9h†hlSj…ds8b„7W}<•°]ÃÎSƒßxv™^]œatx;~¤Gp›en”e]=‰œSv±TŽ´[«¼i|²T·Eƒ‰P‡QÍþXy¤X€«P{ºLÓWm–Bm”_€µ‰}~Kq•Q^q?—šF|­hwÉw~¬a‡¬uehjŽU¯x•¸z´Ä]–º_¬ük™Úu–Ï|’Èh—ºb|°hd’[ˆ¥io…A`>—¶Hz˜a€¬QŒ Pq«R¸m{ªl‘XqtDWyS€QnžUuœyy–Zs¡Tu”Z~˜T±ÑŠÏa‹£q€Á’€®\‚¤r’Åny«k¶z“Ã_y¡Iz¡L‰—U·]“»mžÆue‹Fn”Hj…4rGp•Hx¡U{”K®R˜ºn¯QœJfA™³hÊBÝ×›äEl€Kl–H^†HvEw“Gn•]pŸZs“NmŠMu=q‰[všZ}¡b§À_~›Uj‹Tg}@k‚?eHfŽJ†¤kƒ«_„£E€”IXvAŸ\Ÿ·xi‹=\{7[Ik‡Ce‚Qo‘Mb†La‰BlŠEm–Tm…H`ˆE^‚M`‰?\Ae†Lc‘G}œQ]†?q™Zk—[žD`‚A[€:i†K|›iŽ]ŒOZUwŽQˆ o{¢Wu”PzŸR¬^£Oe=YH„¢^¡lŒ°Kx—?v™CiLp‹@`ƒ4d„D]ˆb¨YbŠ8KsMdŠIdŒIg’Ry¤]”«Y†™^nU}¡o‹µb§b¢¶v»lŽÆu‰°r ¶o«Yf‚\‚¡y™Ãx¾pž¿hƒ±\‹±Ty‘HcOЬd³Ò^ »p¡ÐyÄÞv¯Êd•³QxšTw¯f‰º‘Çø³Ó`—Âlš¿R{›>s”Gh”bvŸY^yNHaH=OIGXEN{<]fDdrIi‡XTŠlavbepBQ{RIeVRaFYl=VsAWoA`oD_xFiqW‚eOgCm…Zz‡P~\„—cqŸkr‹jz€Q„ˆOh—P~Ž^t‘Ch–c\ˆXksHY‡Q=vfWZ?Om6LkJaW=lo0V~<†iF{Pƒ›zj—`d†YpvR„CrŸi|”r\‘WSz_bkAa|@dlPZo@Rm=md5\ƒ/bwDXw5P{CMtE^iFdu>qxLn~A{qA‹‹NzžX|’Ts†OpŒCP‚ObrLwzM~’^†’bh–OkŒ`qad¤~{€Po‹Z~zHš‰G‡¡J‘gŽ·rc«r‚zWbŒ,n}?ŒEl Xl˜xt“]m—a˜ŽZn²X†SnµkkaxE”£Oc®Va‰[r}J,ƒ¬Su—Z—‡Dœ·P¸}b zn~@Z†O‡uA•¶U|Çg•WeˆRkŠM”Em§[UŠfb€Vh}J–>•ºtuÂx”—d§²|Èv‡e•¯Wo¸g~mœœL‚®o‡¢TŒ¶fx¼bx”gu–L›Ÿ]™Â|‹´q‰’sz›S„®\{¡U‡–†™·|c¾gsuHwlHrZ¥…C‹­P™š[мxn›q˜‰C·¥d¾ÃdÁÆ_³d£»l±´r³¹¥Ém­l¶˜mv•Lœ†av¯V®}K˜Ë”¬­ŸÀê­¦¥Ž±žjËÊŽ§Ðhq—p=„zb`?›Œ:®´ —vÚi¥l©¶ñþy‚ÿ®V›vUwD{†AµŸ]gäih}d|‰3“ .©ÎeˆÃ²q¬h­‘I »CŽçŠk‹‚]ƒWcu@w‰Ti©Nn¨]}}P—–7”ºXqŸ\‚¼UrV‹ˆP——DІE–½e€¾bºFbŸks›?pƒa‹©^}¶ghŒv~¡LŒ¤A“¨f¶©Y–½G„¤9o©LŽ›Tœ²L…œ|™¸`Í«y}®R˜¸„²ölÁY€‡U‡˜i¦¶w¢T¿œG‡·[ƒ¸a££Z|¢B°šM˼a­¬w’“[u£lƒ‘7¡ AŒÂ_‚’Pn•Xx†E[ˆJ…ƒOh–G¡“GÂÀ©—·V|²ŒªÅy’Ó›¡è Š£…¦åu¤–Hç³Qg„Ar‹GsF§Kg‚H€ ypƒ‚w•m„UyŠTYz?kžTd™6q“BaŠA‰†RTŠCn’?ˆ³pŽ¿Y¿pyËS­©h¨¾pŠËVl©_w‚^ÿãš±õ\g‡Ed†W†¢YBt4`f'y¤aˆ´p¥±„}¦Rb‘Lh‘QpŸK‚štÆs–µpŠœj¬Ì†šÛmž±[„Áh€±”ƒ³dm˜ƒ¬SiXq ^„³Wqšh„°jfNƒ¬V}•k~žktš^£t~š=Rv4t‰R€’Xh•Qq¥L€²dk•\¤¾ÀíqŸÈi·Öd€©š¢ÐxÓÞÕŒÆVx”S€ŸN‰ Y“ÀH¥f¥½bƒ¢Vбf˜Ê[m’N†¢Nm™SФo|œgo„M¥KmŠ@{…L}H“Jw†]gŽf„™b” Mf‹Q£»hrŒvuS…šB`„‚‚Ir–Uo›Qj\‘“cv³X‰Z~½Pi–†–{V¨–J“Ny¡d—–V‘ÁW›Äs£À`VÄ‹fr@X‡QhuDk‹DP‡^]dKz};mžExDlX[~MstD|ƒˆŒ[kœez†O„›S€‘bežcyŒap–f~‹[”¢T€·d~§kƒ¥Q~¢dm•L}G¢ž\v¿t›™c‰j| Eƒ™a~ª\¡L®d„™\£¥I¡˜LвOÜ«Lµø‰‹Âe~¨`žYŠ£M³›f®Ðd×Ó–”ò¡£«ˆƒÈf“a~¢œ‹|p’¦M”°w£»ZÕ½[–ÂQˆµY‘´hy­I ªO–¢ju¡Œ—Šº¯m‰·I„¥6¯¢xŸ­‚ÑÞ:‡Æ…ƒÆ^«®XƒÉ€b¤¸tDbœPŠ’6°˜` ²|‡›H’¢7c¤R}heuŸcŒša{¶_wœun­€–|Ls™9ˆœD¡¼?¦®N{µV”„N|›?…š[zœh dˆ x~¬R‹©hˆÕa‹ gz–h‰Š>ÓžFiµb‰†2‡ª^‘V¢=›—\¯Æ\µæ[­ªo€»‡‘Cz¢Iu§|z¡o…‘1ŽÏ|—¾pŠ­x‡_“ÑÙƒëk‡TšYw’y–«Oº”Q{§‡»¨ešÂ`ŠL¥ÎZ±Îjw­Z‰Y¯ºoŒŒDm˜L’“Yo‰ItE™Bip8“0n‡E|=ÿOnÙ{pŽTŸH˜Nz†Lxª\ƒ³z¦oêÊ“†”[‹ L|“Dr„QduT^‰F²ËY« }p¤€j|Lˆ‹7Œ§D]ª#«¬Enž3€{?v‚-›¢B‹®h˜Â`t’KsŸg¸Õ”¬Š„×e†™Sˆ;ÀóÿÈà¿Â·R‚ÍS[€Fm(¤ÕDŽªayšItnz‰Sn‰Ksˆ4ˆ’CnŠBpšf~¨~q¤I€Žp›É‚‹³g ¹~‡Æc„‘Sy¤C–´Sz«s‹§T€ŸE_sAªRˆ“@r˜X„œU‹™n†Žg†¥Ve‹dx‘Uh€@¥`h‹`—BqN’a›Øa]†nu‚L›¶Q€¨Py Gy°S|¬co•O{¥Ur’Cs™[fP{¡Yx f~¤T†˜Ml†FËN¸Tv“@œ`Š£_„£Xг‚޼ƒiRu‘a’¶h—·rÊç¶aŠHo”LqzF†¬Sw¤VŸÂ†Ázr˜dy z˜¸Œš­o‘¦Šž°išº`«^z–S¶Õv“ºQ¯ÆTo˜P™½Un‹Km‹Fœ£k©¿\”²U›¯YbKp”Xg†M`ƒJh…]dŒN`†Hl‹bƒ§QiIbƒBbJdyCh\qAi‘Wjši}¡_‡¦_g‹_³V{šX§esšc»kf‘XhOe‡Sf‹Ea‹M…¨V~Ÿf“¼w¥À\eƒGr”B\‚5Z{Hz Pg‡;^|CcT…”E{›_—»v”¬Yh„|x9p‹DfŠMiu@ƒO}˜C‹”Qn•OJlh`>}ƒ(m˜G]ŽQSyROpSJh9v\FmSx~KnIYwvxq®Œhn•iiŽkzˆMj™:rŒXx‘BciZx_VhŽžW†œdšœEkµT~…JvˆGo—OpsCŸ–IŒµx–¥d‡ q¨LpªI~‘O…›Cg«YnŽ\«ZŒÈ^¥¢’¥ky°pÔ«u•än¦«_бj”Oí°wÁ䋎²˜pœp’qš¨dެJ¢¬m‹Ìr޼\€µV©ÃsoÆ¡Ž^‡ÈiÓªY³Ùk–§dO’W:i2eW-[n›GoxX¨™fv¾f°€g‚ÎV™MVuN\fEq€%mhG{‹A‰\œ¶žO‹l„kCk™sw…‚“oŒ–EÂtIˆ¤H~ƒh‹“c_U±•œêX†•M‹ƒL¡Lz¬W‘Žr‹Y†µN…«:pU´¦WeªFº€:Œà[ÄÖP²™Em–Zœ—G¯ÚŒ~ÇG“©}Ÿv¢x¦Z„žr‡¡Aƒ˜Dh§]u‹DlŒ-»É\j†,ŽŸ[{§Vx™@Ò˜M¡î€{6•žRwÉiŽ£5„_¾A‡”Z¤Ò{‡‹ix„Bq‹`x™JTz/zˆEs›“®‘DÆÿˆ‘8¨º`©¹]SžHui=‹”D‡°Go¾]‘Xo„QnZs—H›hˆnS_…`W|ityW^ŸhRbQ¢’›×y‘­b™ L}—ƒµÃ°¹ìhsœGq€<޳M_ˆ8w¡@{ŸM{£:p¥?v‰U‹½Y¥Á[Š¥c©c—¼m˜ºb´á^”ÌV‰•Tš´l’®f‡¬meŸE´Ì{{¿\Ÿ¨p•¾tw—Ntˆgr¨hzAlƒMe}Cjˆgi«?h‘[sZ|¾^fžK^zfƒQuŒKiŒI\~CX}Qd†EnƒLrˆGdzDe;Xs:[€Hn–g|–`cDdƒLWIKs5[I‡ Mi—Ys¡]bfdŽEo¤jg\i‹Wƒc}¦gn IpPd‚=]SfŽX{ c›Àj‰«v†¤UdˆX‹­gx’L‚£j²ÐZx›L|—M•Qz‘^z™Z‡´o’¸Nh‡8`~K}£j~¤Vo”lqžfn`{•>e…fvAlxDqŠLQ“JfŸYXƒe`d@[xAWpOLi9OmGliHjO}~JwBiTnwXcŒNge€}Qi‰KR€SedG‡ux?c‹E_€Vin=y†Gr‘=z|\_Y\~fue4z5i¡ZkŠ_zzAUˆ?iiLnp2hƒ;~R[ªEK|e[f@~yA¡”V…¢h^¬O`O{zIj¡Bxˆb€sL~€JpZjŒMouB‹‡3ˆµ>°¥Y¦Óf®Í€œÆt¹Ëˆ¾¸nÂÜ€½ÜŒ½ÐsxÞps\‚E{©Vc r‘’Hy°V™•R–´IW²]hsQw‚-f“U`„BzzSŸC}žWz–^¥“T~»ešŒH«]’I‡R’®ClžX“Zh’|–‘X°ki–N—‚Hu¾M~‰I„žN‡O\¯b›‹xŠ»g€ ‹…œi~¤k~šUŽXšªG‹±u¥£xšËfx£Š´o:˜Ú}s¯m“Šb•š^ùŸ^¶ÿ‹Ç³£©h«¹UjÊeÐ…Z·á]йdÚ©L¸ývŸâŒž¾{€³rm˜^˜™V†¥‘’œ[Œ¤lo’7ˆtY¯?¨pL¸°M§ÇJ‘Ép»§I›Ôm¤¹c©hu‰4®‡@¶¯YeW³}A¾àX^Àt†r%†œCx}Ri¤Q| 8j{CQy0ƒn8ǯSƒÉuƒ¨“q|k©”n¹Ú‡ˆ¥’…¤dv¤~{q5t”IªŠMoh”µC~äUu”hd3r¤er´cx™BƒDŠY™µY¨¶T³Â¤‹¢@’™Z`~Q‡˜?³¾[¤s‘šUŠ¡Ik‰:¥UwŽC¤œS€Æ_bˆ;Ž‹G‰¯su¾G£ÕªÄùűÿ’²¾E¡ÿgà…ƒ§}}›bÏjl˜C§®CuJµp„ L…¦^„ºMo•Q™sGmxY€Œ\ªY„žhª°X¡™rvŠ8¢‰†ƒ§`YpœQÈÀpˆ·[}¢y«\Š‹>˜ C‚ D|¤>}ŸV–¬bÍ»‚‘ØÊ–©oÂøtÄóruŽ?ƒ“LŸŸU‘°‘”ål’ÅIÔz}©h–¦fq—J„”Ph°cb—BlPhxEm†)†šg‘¡…U~_„™_±Ë„«ô}¥±…ƒ¥\Ÿ–H”™i‡®8xŒO‘±V|TaƒU›E£®€¤¸ÛêÊãaãì§Ù¯»ŒÃðˆ›åcšÓw‰av¬hj„G‰¡ov™g‹£ay’tt‹Q{@o…M|›KvŸNk‡FrŽAy¦`i„Fw‡OjŽZhQz¦U{¤fŠ­\j¢^v¡ax©flGš¤{‘´mŸ¾„¤É[‰¥Ly”`|¦U}«Yb„N™ºsƒ¯js¤[i~Fe‰^i“W^‹rsœ_`†Q©}j”l˜¯Ww­j¢Äw Ép€¨=q‹1—“O•²E¬Àf¢Äy¸×k™²Q”­F…‹Zœ™Tžmn˜W¨Æo€£m‘»pa‚T}š\|¦rœÅiž­VŽ·S~¦]}¡or˜m½Úki›OqŽLb†FgŒ~µÎl¶U›;rŒVo•JrKR~2Mu?V=p’JiŒMz‚DYƒ=d„=TwH\…]mFr’G{žLc;_=aŠLnœK[Jm”IZ|Gy¡@oš[`~?g‹S`‰d´aŠ·Uo’Q[ƒ@l”UtŽH{m½{¨Æz¨²Up‘]vŽgbŠbr›Ž‰³lu v²Ïh¤[™]‚žQu”f‚£WjH|‰Nf…`ŸYz™\|žUf„Ts”SzšGy’Nu[tŒh¨WeFc„NiZ{¤f–ºeаesŠUi•m•½†°Ú‡¡Èгæ‘ÈáošÆa‘¿Mv–NnˆfЍX™?FlTw¢xœÁ=ag+LgGs”MN`;BN0?D.eg>gz@a{ORrJdcKfhG[€TO‚OJbHVdVY]K`i/Xt1hpBvx>XKXn[rqFŒPz™ev–\iŒVE‰cBXO\F2Yf;‚o?y8k]b~uYrhbkZ[IhjAn{7qPk‘D~Vx’V{_y‘dm”m]…yaiBTy†šcu–_†¥S——E—¼\¡¬M˜ [²½lŒ¼’Àn‚ªB©¬P¥ÒrÁx›¨O‘¾z‡»bÇZ·½j¼Â_ÔýŨç’v¤T«¢Gʤ[šäWqˈw¹ƒ³c°Ë…ƒÆx‹ºU‹¤SºÌŒ™¿_†–l”ªqˆŠ[–Zt—R¦Ž™c†ƒ<|x6†•sx§c¬M¦¥^‘—`{µIˆ¸Y|…^m‡@ň?äx·Æ™„ÎPvžRj—9°ŠD‡¶l¡³gŸÝp™¾Ž}˜c…€Y‚ªuyÏŸl‘|¼R¥ÔY»ìt·»a ê«˜ŸsŒåz…šU£¸y™¬t|™R|„NnªFSŠK}šv¤ÉN¡ÌB»ÖjœßRÑv¶c›£j¨Ãƒ—LÃׄy›Sœ²b…¤NžÙy„ÍkxŠQ¡ [£É§Ïk°¸–²Ô¬ËÌÏŒ²Z§¿i“©£±„‹•€sŠG‚µVš’M{aƒBŽ™gˆ¾Y‘«ChŸRo†P}™We›M˜J^pGœ¤o~¬K`‹DhIi~J€›e²¯fo³|Ÿ¸J—×_}¢TvšCx’\¡q›®˜À€\™Xy—MªU„žnl‘;Œ²vx Rk•PtŠbiNŒ°LWF]zC`…OºfrŠn“¾tz©]¹x Ã‹«ÔvšÀK™Y¬ÏjµÒË蟤ƙ¹j¤µlv•Qƒ—R˜ f¢·a˜³… ¹o†•TvN‘W¤a“™W}–`x—Xƒ¥s’µb…¡kžvy RmŽKbˆEXxS\„“ÃÕŒv Hpco’?VOs3`‚CmŽOj’Ks–I^€8Xr@{˜>^BYx>QoE^Ak‡SdDi’Sz”Ui„;\„Gh‰@_„Cj‘Kf†Ie?kŽKu‘c€§mйWX}EmWgšT‹¶Rx•Vr }†®{x™o{ŸWdˆAf„TzU]ŠS€™xžÍmy’Y‚ qЧZx”]q…MjŒYz—H_zRdˆWkZz–XvŽSp’Wv˜b}—TwG`{Xa†E\~Fv¡L¥f“¼„¨Ì\gŠXh‰CdŽht™‡®}|­†ŸÍ˜ÂꂨÆu±Ñw½âp±Ñj¿Ó`¥½m±ÕO§\˜½t¯ÚY‚©B~šLo™I^z1Ul9You{EŒ|Cp‡I\|JupÏgŸ S¸L¬¦P²ª]Ÿ÷€i¬Rl“P…„f›‹c”̆Áªg›²SšÈ}‹fŠŽc}c„¨Ÿ²p„²[pÏKv Fl¬P^o5pšoo„ao¨e†¥‹¥½‡²\n¯š{M˜¦l…°pw¥pzŸPc–>lžN¨Uˆ»wx¤zŒÆ¡c¥TŠqŽ“X†‘f›°Q‰Q²ÿ”—„F¶½x¥ÑdÞik‘YtžN–j‚’XvŒm}–]Çj} cœm~™j‰T†¢cp IgŽQ|“^u‹RrE¤_y§U²Ïu™µbz©Yn‰?¢_z»`‹ lR~8ž±‹›Êa”¢Ww•I¢ÓUz•N‡¹Ž_…OqŽhÅn“°k~šJ–©_œÚy†¿táÑtªÁKÉÇ‚ƒ¾]l¡IXuO—c–µt±Z®U}¤Nv‚Z–«;§Sn˜M}“`‹®\}žls™f|£`q—y«rv i‹¶[š¿vÚÿ¢y w„²n˜À•µàˆ}«H‘¤_Ÿ®aŸ²d¡´q­´o\‰H‚s±²e–¯a¢´n‘²XµbÌßz|§me“Jg“dr”Gg’In€;\s5ZlGj„ˆ¥»[`…M_5`x<}žEoŽJ`ˆEp’Lf‹N{’>h€Tq”=]w>b†8Ns3Ln8e‚Im”Qb‰HVƒJmŠOu”AcŠJo‘FuŸSm‘Bs–XwšQg’]n‹qz›^xž@g†V¢g‰°QjDn•ZsŸ_¥g‡¬\p™FlXyI~“Xo‰w£Èwwšaƒ•]q‰W]‚Tc‚Lk€\z–SN|StŽNf‰VqŠJ_}Pr”Tw‘Ks‰C[v>Tw<[€Lk’a|¥u‰·}¦LfŒJo—Oz’W™XeQsœ{‰±˜žÍ…Šªm—ª~ŸÇ|ŸÄ†Æ~”´v£Ë{¬ÑwŸÊy¡Ïk™Ïfœ¼bm–^›²Dw‘Fg…O^p9^r:nrLcqFy€=ˆ‰GwœYr¡pmbm„^€QJQWjd[e9Yi>bfBeBlDjUg€G_ŠNsV}‰P…‹UƒMz’Q„ƒToŒDi‡_asQnkEs‚BX‹Rmn\q‹G\ŠS-oMA;NJTOd=s`G„‡i=\…DoKT|B_ŒLc‡DNv?]‚]}¦J{’>Z‚=z Hrž=i‹Ex‰K]€DkI‹¬h©ÌdfDl…Rh™_h‰Iy—Z{ WxžSm–Psœc|¢LmKg‹]wšTp¤Ro—b‡ªi—´j…©ep“LmX§YsŽKbXe”k„ªgx˜]†žJbˆL_~It‘Ux•Yyžj}“UhŠGl\¶T—d”²gœ¾WzŽE`t8e}?X~Jp“Xv—]j“[lScˆV‚›cƒ^{œLd}Kg[w›{ºqsœh¢g–³w•ºlxez›k¦…š»x“ºo—¯iµpž\xšt€©RjŒG[{\Œ>W†fiqPvH}€O‡†Dt‘V`ŠdL„SVbAcX6cn>osZo‚\ƒ‚MŠœWq²až|†O”–P™n¦vz¬yR™eacKN€UJo\Og7Dh1b[Apy8\‹Pw;­`œÅy›Â‘†Éªt¯hŠk‹„YZŸ_y€X€S–Qr¨P^œlcvfq„U”[i´q‚_«_šºe…Á\i­n¿v\•¿eXŸndbGdzD^xGNmSm`3¦–6…ÐW§mhŸu™Š[µUf]Z|Mb~;~wBn©‡Œ¢›®ŠlÁ~‹„]~«^™V†·S­¡[¬~ƒº|¬ŒfgÏxLnV¤g#›¹^½¦PŒµ` ±r¾Çe–¦gp¶ˆk“‚°pFÊãyÜ•¹³rš¿|x¿ˆŽ„œt¢²GÒL{¿whq“’I…›c{¯UY‹MŒtb ³jÊ~Wvh\j2u1}“T\~`—t)xš<ˆ _p¡[ŽiAêÂX†ëgY‘>ªj0€¥V¨¬Zv§…–k¢nm‡Yy˜L˜ˆZ{¢TZeˆnGˆ–o„Ÿ[Œža•¦MV¶{uo5b…TmpKzƒJ’µ?j™V\‚I†‰5c—M­n>ñy’ŸI¢¢GpšHu4„@XT„[)êѬjÐTvŽA²|FpìjFcŒtv¡]v QoG‚·mvPŸ¯S»sƒ¦i|©Y¦³x€’t“[\†Yz{B´’>ÑlšTÈU|—=c€Ox5À¥Z^ÿ¬ ?v“EYZQ€LœUt—R[t{ƒ˜S´›MxŒ–¡…?³’U€‘aižM‚ªPz@ižl‡y:«ª[Çĉ‚¢T‹at¹w‚°F‚˜N¼ÿ˘–[ŒãÎŒŽv…ŽF®—C¼Ãޡߙa“l™^v¾XŒ¤T€›V’¹€‡£ež¨M“ºnšG{ivP¥•U¡Ou’Go¤?ˆ¡JZ¤:wOš jË¥‚©Ðmµkˆ¿nŽ´I” JmžG~‡J‹‹9£œVÇä^¦F‹”^¼¨x˜ðÆ{‘}ƒ˜Tw|k‰©€•¨pŒ˜W‡±f‹”W‹»S€žYЦN‹›T»¼dµÀ`³e Ðy—»b‚°]©³s‚¿}zŽHƒ›Cƒ«Hz›@|–CŽ˜`—YÅŠ¨x~œMaŒB¢j‰¨nw¢a½ÙŠ­S}©Yïôušèvåÿ—­æz¿éR|‘@·Ñb¯Ï[„£Wz˜I|T…©p—­mªÕi‹³Xš¸^s“rz£bš¬‘ŠÐƒr®Mx˜BqŒb„¹bc•Ev—\}¯K~ L{¯elŽb{ŽeЬsh›`‡ŸR”¯bk‹Ay¢Pq‘b•ªfnw^q‰W}h °]°ËU£·ŠÀ®…º­nœ›¥|ž·Ut¢OŠªQl’ul¥l£^«Ä}޾’³py¢lƒ¬q”²^€­tЏ[Œ¥SV|/\u@i|BfŽP}©n¬f–ÆgÖóZ€£H…¡>QpJwIE_8]]$rd$mŠ8\ŠKgx]yC~ŒKw«]™mu‘_aU€|L”Ž=l¨q|„gc9N{N_\Fyn.cG`yIt~[†ƒWs€^]ŠYkeDkb+Zo>Qi?Oc=w^?ªŒP޶rˆ©z‚›[•Wp›k†c„©dR±vRgOOp;wg;d7_€>w=€›4n™b‰G¤R}®[œ•l­¿–›Ò›œ£v…³^£cz‘JŒžZ§¤S[×rI€tjY0—|5‹¹[_³‹²mP¶¼axÖ^qficzDgVm€d€H{¥Nn–WfžJxƒ)ˆ<~¬mr—u€i¼—HgÌŒ€l\§–;dÏO‡oC[›Ng}S|{Bc¤‚–~U|±Še¢ßh©¡i—§y°ª[‚Íe–[_ˆF¿x0ÿÌPÇ÷yÞ¹p¨ñ~¾Åk»m„oo¨‚¡Šv½žZpµ¥…~EÆ‹eÅ~X‚dvk<Ž^’¢NÓÍkˆì‘g¤`˜™S›°dy¹pošEu‹K¯¶[‘ßmÁwx°R®¢xtœ^•‘7€–t{’F`|W†‚9É€e´úÍ¥Õg·ª@¨©f°{JŠ«‚´Rs«mœE¶±]ƒ–\•ˆHŽŒY†‰a¨C³X¬œ±Œ—™mŠIb‚N«>³T¤¸]x¦[n™d€¦Už¨ep¦P‹Šbf¦R¤nz™~uŸ=·˜XX Wit‰”fe Ýƒ˜c¡»…¢ß·³Xq;•=‡©Hr R“¤G{»T… Wwtl†“o¨¤Nx²iŒ¬L‚¥Yv”o‰¡B|›Jv|`rY¥ˆd›š>d§8‡”:²™Lvã×´†OÀÂ…¢¶gw>eb^Aer2ˆ9ÿÓ…ÿÿgÑåe¿æ]©ìrsÀR”ž`}±eTyDu‚<ÿˆSl¹vpT}‹Lƒ˜;j†ËÄ“»ê¤w¢W€žƒ…¶gˆ¸mþáx˜Õy†”£FšÍqy¯[|›SФJlZ˜Ž… ¼‡™”Rw¤fv•R|²?Š–R…¬R‰§_q”Nn˜M]‚6WzCjqO“|ÒØl‹¾eƒžhwŽd–±hÀÖZRLYIkn:rm5|nEz–P—^{O] dvtYkƒVh[ytDp‹?V‘Sej>_‚0jvA[†LLPUfIhe9ƒtAuœc‹u›c€¦f‹“gˆ–N€ m…—ly¦Phœ^^„Cnp;\‘G[rH‡vTšL¤“Zvµek˜d…rDŠM[™OauPpr8‚…Xp‘\kŒuˆg¨UuŸh}˜W‡ R¨okZh|Oj:h…WxFx–TfœP\jc†WN”\^lVŽyD–»b’Å™—¤|¥Ïzƒ×wz£ko`“ŸTRÌpotabt#x=–ªmsÁ‚xXœU‡µˆg ~vy=_8pQ³“BÍ`£u¬dlÂgw”Cp=R‰gwqd†“AžŸf|¶mŒŒQœ N”°n»šXnÃbŒyRYšE†hQ«¢Dg›ŠY|P_tB“{e¤Y†›|…§]s`s—8Ië‹Gè¦M¶[ªµ”§Ã¡¼“ …v”j{nEdwO“|ZŒœRšz>Òªu–ìŽô§D‚䎟Ÿy¾xw®„‹”Xi†K‹{?‹»qh¬n~|J´›7¥â‚ÀÙr“Ï”©½[r»Zy‰\ˆ˜Oº£Q¼fnIw“Wˆo—™wâ¦v€Òl¸~XOÍœ“d;¯§‘ˆ†F±•CuWatPg}8²‡A¥©qP¨UrBi”gyP‘£T‘›LºÃu…·yŒˆ\†P\Ž@²zA‚鎉™©€¦JfRr‹F‰•oƒµg‘¯wo®\†„?\˜W—~CzÄy€Œd›Çp°¹fyÆdRŠY~}g–ŒR™¶x”¹m‰ÞNt|K•¯_¦˜[f‘shªZu…X|Dƒ¢O¿¡nuãg“Tj†Bª^‡°…‘Eš’4’ÀЉŒOǾ‹ÏŒƒ°Jiu^€}7v{@É}žªÑ¶‘¢þº¹{—“zhº…p~TŽ}LŒ8†Œ?Ÿ—T°„¢¿B©¯>—ã€q­Uæä¨÷¾ÁY‹›L…“Z±”Œ´­‚§zƒ€K¢¼oœÊic“”«Sªq¨7—»d„œ~•[Œ’i}²‚É—…®er°\ž–Mf“Oj‹?m…?„‘D¸½O~ÚTúÛ”˜¾z”ÃU‹ªX’ŒR¤«uŽ™O‡¬4–ŸKžÑzÜÒ˜²Þ^޵«²¿¬ë]¨W”¯T˜³`yªH¦Éd†ÆBÁÓ‹¡ÊVZ‹5›R‡Z±¸w¡Þ`žÁvŸå’r¤`£®{šÌ[‚ S‹­i©ŸjÉl‘—_š›M„¬JsœOh§^‡¯dOu6e‹M‡™X™¸a_‘8”ŸŠš©}›Ú`q¹u›ºZФ@x«iÏØ²¢¸|ëÿ¶Äü­ ÔžŸ¼`yªr“dfktœel‘k}¡lrsh}«kq¨puŸ]‡ª^…žU“É]ƒ§nŠŸSÄÐX‡»•„Îco›Gh€at`˜¹pižGft¨Äsˆ@z…K}¡Tz¥rh˜@gŒU®b€Žkg”Pyˆ|†´g’Çt™³_ˆ©n“±Œ½•mSu¦€þÿ«ÝÿeœºBO~E~˜Ll™c„¤XŽ¥Mt–CaŠ@j‘Tt–N„¨Kvžrr•geŠWp”WxŸTx£_x›X\}MkEiŒGj•>oƒBiZnœQWy4j’Mp—Uu“]˜·Y‰µp‹ªT{›Sq…Pw–_\{5kŠJ\„Gp‰Iu [йe¤T‘µj“½Tr”Lb†G€¤ežÄi‹½u­]p•a}£dh’C\‹Y…¦RnY}™Pg†@e€Xx‹]Ÿb’œbp<^zCg†G^†VqLi‡TlŽMg‰NjRe…Nch¬d‘¨ZhKW†Ujœm‰­bs¡o¥\qJb„NwžoÇp‘ªjºaާi Òt ½\~•Z Ëd¢¾[’ªJ„žbž§Tl†]}œ{—À”²}™Â{¶Êj†©Ut•_t“au‘Xop?||C¢¯dŸ¥k³W¹h±šorxw›—m’]–‰R«ÊU—År­Ísf½cu©…¬¨k¼¾F̰iÿŽNÿÿ_ÿë…|¬nicއ8€­r–’p–ºdc™dÆ}¹†{¦Vl›D}¨T‹‹_¤\a’AˆšGg”W—¨pÔQt’k|¨lnÌÂ[€b[¥k£”X„¸O‰‘O«i}»dh©@‘“PhŽEtœVž›A—À^šÀd¦·”˜Œ¬Ñm©År±Æw¬Úˆ¡ÒŽx¤_¥»i—Äq Ù|ªÆs‚¡q|µC‡Ÿ^‰’od“Mš†[o«ti‡]k^t©g•¸¦¾±˜†¢?ˆ­TžÆm…¢o ¾zŸe²©¥‹¨I{¨ˆ·t€¦]fŠXušx€ [wŽP…{gPey?^|=TyE…5p‚Z‰V€«ut¥T‡že’·b¢Æ†ªjz‚j”¹¶Ÿ¨ãÉ̘§Å¥§Ì~™hžÈdu£e Èiˆ¤U~wf’Gf•7csGVzcq›Nu’nŸ¤l½¹eÿÿ®ÿÿÝÿÿÿÿÿ~rc T…”R°ØW‘¯b^~>m†Tn˜aX6b€KbˆInˆm]†BGqARtIi’IkˆRˆ—cº¾{d…k‚•uq–X€–[‘¿kŽ·Jm›f¤»Ãªé‘±k|§=•¯K‡¡T–¨\“³cŽ¢\ƒ¡M}I„§dl\g†HYƒ:c‚AZIsœYq“dtŸ[\wMWv=^y\o‘Fw“L‰¬Zk~G|’L`ŽS‚¥f‘´^†²m¤¹Oƒœd°LŽžaƒžDvŠ:]w6gˆRjŽU}¡iš«dtš]g•uw¢O^zGbŠM¥mžÎx›Éuw›Nj‹Ns˜Pv¨Ux›_nbw¢\|ŸX‚ŸOeˆM]|Q}£p„©k‡¤I`~JmˆCsŒPpŽLg„CXx@i’U}§Uv”N´hœÀo~©Wp‹Je€Mz®f…­]j“_o›YgŒS~”Rnx“»ŒµÓ_w˜\‚±€‘¼‹²Ëq§»k Äp˜½k¯j„´w{–Uƒ‰Zšk†§hmŒoŒ³—²În™°\€šWy˜a‡¤SCmDI[ESX1GrAGfMC[?Md~†Lœ‘G¥¨tΡ‰žÊgÚ¢M’ÈZÀ„häL®³T‚ŸP¦ŽBÕµ]¾ëªx¡‡b˜AU„ItfQ“N—b:…ªN[ši§‚^”ºMs²p’‰`Í…RÓôv›ý¶Ç‡‡îû™’ÿ£±zªÄsÁÐO§é´ÇoŠÕyq³u—ŒpvàN‰£Uz¥„—©`®³ƒá™q¢X‹mf—`qo/ƒš=˜°z®»ŽˆÃu¤E€‡NÂÀg¥Ó‰cµWZj3„rBÚ¡cŒÒ|ƒtq˜[€zF]Ž.]t8Rx&VrIf^?w®R†p–d€£hužpr±U~–p[}=pe:‚`rˆI¦xJ_µ`^kL€zHtnz„:d‰?f‚F‘­Pd¨[mz?~—N‰A‚Ls®uy—o¥£L¥QhžXY‹=Yp¤\g”9r“@²¦esÄŸ`ŒX®±`blt{Vg˜YfˆBtEz¢Ajj2ih/‰„Q•§K¹¬e¿”?ª¾u—–a‹¯tš°^²E ´h„¦}ƒyE­ÿg]|GŸ‹NÿÍYÿùŠÿÿÄÿÊzÿÿôÇÎÃÿÿØŠÎm“ÿ…†Ù¤ÔIo±ndžAu“nr“sfZ]@qelJŠ­f†œ\ޝet«h“«€„†U¿}®—lÌ_^ˆ5x3‘¨D•è‚Rl7Ž[‚Âdrœ_uµuitDy@|ŒP¡•\ªÙ€£d©¥T€°|tŸiŸx¥Ê„œ²t‡Ëc¯Á[j¯{“ar¯qv§Vn–\±T›«cžUw„Lj‘=y†[€œOm•qj­;œ¯v„·e†¡S‰¤d€¼yÅz~¥]š³ˆ‘Ô‰­`¯epœ_•‡P†šQš¸U‹´F—ÀX€¡[t©;d˜Fe‚7[hLrD€ƒXžµa“Ÿj²Ñyœkƒ³r~”¶ä~m¡ar[x£rV~Z”®`PpZtz ‚‰Áo~ŽnŠ­{r˜Yvg‹·Fg€BX„J~¯H‘Nh”PlšR`„Wÿÿõÿÿÿÿÿÿÿÿÿ¢YXn[f}ar£c¬Ðtr•=q¡Oc}>[p|®GxˆZx•Ey›neŠOt”LcTxŒFv˜l«p…¬d»Š‘ªg³Ùex c£¯…¤¥\Š¢fh}In_Œ¤gi‹Xp‰Mi‘Rf“C\‚:WuiQ¡Åzz±]ˆ­…ޫбÄgˆ¨oŸ`Ž£Fk‡8Oz?e‡To‡V¢²frŽIe…I{ GS|Hg‚Gh‘d‘¸h|­gl e|™B\}Kq—X‚´Tp‘Zj˜d Ìg˜¼a¸]€ B]‚L|n‡¤b`†IaŠT£Yt’KfVbHfƒBw™a¤e{™dŽ´nyœXcˆWh“Sf‹Oh“V[„OZxPsRaŠ\}¦]–¹vº—¢Êv‹°a{’fy”v”ªz‹²u—½j’¢jˆžXi†[tŽ_pdš²b•¨\™¬r¥´y¡¿x’§c‘¡Uƒ–dˆ©jWb”QÙ•XÍç}Ø£¯r§sGsOmf1x‡>PŠTtn?­„\ÿ¤f£ï”£¡xz»Š¡YŒ™n´Šd‚Y°›Ko²`{†hœ‚x’¬Tu¡@Š|<„~8~ŽDÒ‡EÓù¹u¤œz•Q‘¢]…‚q²¬O˜×£ƒÓÐY|n„|SQš½PcY‰l‘¶‚|¯«–YaÚ˜‚€X”Oo©QqžT—F\š:tyP’es¯cMSna5¼‘3˜Ëw„Èk“Ÿ`—«u¢i«Ò|WÆPf†Q{‡p^?|}I’µJÀÏѳ׌à†ÁšH§­zpÊc¡‹3„¨Zx4j}F‚H’ÇY“žX•ªA[©c€Pv×E}u<Ê•G–ÿ£¤Fy©ozšH}œP™€|Áeis5¥¶Bˆ·w{˜Nb´[gtG‹IpŸXޤM†›4s×e¥HwLZ€4UxKq‰jž/º¯;rÑuu™ekXÚ­ƒk¯]lŸ6m~AžTvÌ\pš__~9ju5µ“b‡’i‡[‰ŠG—²…• TpšSœKˆxx£Rf]O…A}¯_”kÙ‹aªÿ³³ÿ­ÿã¹Ø¼}θeqƒ\…“¦xh{‡[—aŠÂŽP‹]U_K`o?h§GbŽFct<ºHp˜PX²i”†G‹Èx P—TÈÁceÕ‚e¦Vmqr‰E»¥qmt˜X~¡Go™Fš–J˜ \š³Iƒ”Y{¤F}‡Yˆ™SkG{«czm‡gŠ—cŒ¥l‰¤R¨[ލZ¢²e”¹Jl…Yo‰R|VpžQ†›d¸Äy¸\jŠE^{YqŒLVwJl…WmŠA^€4m€Y¾Äsi‹daƒ:`wS‘­TYU”±aޏttœY|•|¦wtœ[‚žWn‘Bj‹N®¶T}•JYrK_NbŠBaYƒ£b~“I€¤Ln—h”´t…¢VfŽWv™LY‚Eyk‘ÀVl›Mjd}¢t‘¼„ªÎ}†°La‚Msc…™Ri‰Jyd ¥eŒ¤TsI\…PiŠ[h„Um‰Uq\mœP~™HY†E]„Tn’UhFWwGj†Fl‰Gn‰X{žd´j€¤fu˜_|¯_‡–Po“a‘¡h‰Ÿr“°i~…XrƒKi{Nk’Xy“f‡Ÿf~šf™oŒ«tz˜c}šc•§d{‘f}›j\^2Tf;WhI`jEhvDXzD[zGhp@pƒBnJiŒ`Xu^XoIaoHgˆ:kLRƒGKkNRhKLa:Qb;bg8jt@ˆ{HŽ˜P‹©ds¯q‰ŠZž‹Y…§g„gq{X_q@p<…’Ni–^sybgrHRg?ShF[k=]l>h?¹kA~Âh—›››L]½cˆ{]x’4‡Zz§Qk]€ƒbXn`mXmgOX‚RziG€†= ›Pµ^~¥z€˜h†›^§©wƒÀgˆxŠ“^•¥K`¨Uh‡bŒ…\w¥el¤zbŒkWxMwvJd‚]r…pwx?}†AjCzŒK{—LŒ—\c§fi€V~ˆLŠ•]£Tw¢[ˆ‘^ySt“P¦‹7—ȹz›º„zÉy‡¦q‰®~‰¸`X’qVn\nj*x„<—bÂáizÕ³½ŽQ—Ùmœ—lôQ©¿W«n–ƒE~§l¢š‹y¬o¢k€•Ts–DQ…>B|6hl&±|(׺\ŒÊ’–k“½W†}@\†T€mQ³H¤ÝUr ¶zGÄÈT–Èw¤‡„ƒ}=Yn‘m†‰QlÁtmx’T„I†­O|°b‰˜±u†©„C¤=a`TXr5ig8zyN£mv¬kc”sp{J‡>T…Ozp6o¨Kjbwir¼j|zƒ•_bwNpnM§b•逈Qg¶Sd}J{ŠeR3†Y*|›)§éTZ…YW‡9ttL„’6†¬]ŒªV¥Y£åwñÿ®ÿÿ£á{šÁwp§Rp¡>}œ]s‰Nb¦qy‡dr¯wƒ¯P¦³~£È›‘©K„›UÉÞ“’J§œz¥Ì^v^•‹‡º{‹¿{¤¶Œ¯ÿ…p›…ƒ˜‚pˆ]ƒC̵…K}mi”d‰¸X‹ÈJƒ‚Kp—Ew“Ej’Fv‚Gf£TŒeƒPr•L¦¿m¬Ú…lœSr Y‰¹XH‰2}‹Em˜ap^xoVgP{‡PxŒf„ËbyŠM¯Ö»vžHª¦ÅÊx~ªdާV¸ÇUš¥P‡”^vœRv•]… HazVx:nŒS€ŸTa|]_ƒ[fŒQl’\sœe]‚Mn‘Yvœ^qVv¡wy¦Uq£VpŽNj^pŸtx¥p‚¢Nd‰On–cˆ£O\‡Rn‘`o’_‰§l—V~¡QŠPrŠY‚™Nl…KlQ}ŽGU€Pm‘K]yF\@]{Ol‹ElIh|Oj‘VmSr˜TsTv[v‘QmŠ]|œ^“m‚œ^‚’Jh{P†ŽQp`~Ÿ^—Z„iŠšbp‰Uc€Ua†[}•Pl‘[y–]M]1UR0OcqyO]xPboCtk=Šn<¬p>ˆªXu¡–}Zr¡ns…eŠ‹J—šao¾qJ‰kZ`Pyf4f…Jba>^r9s@zœF”•g…µcg£yfƒmw~SŽX…žk¸•l› cŠª^n²tpbd‚BQ‹R|hR[›PQ|Slm;~8^›SŠwE˜¤X°eƒ•V€œj}™W•˜eƒªWŒ®Kt¯nd‹^tƒh—–T€²Wƒ™rŸ–F¯Ï|–Ìv„¾|œ¥f³°h‰¼_ ªYzÅpcS‰x4Ö¨:Ýó^‚ù¤Š¶Ñ§V€åžœ–¨Ë»Xå³Ä±g„ÎhpšjvF‹}Q™¤Vƒ°i—¡re¥B‡€9hE—ƒ*Ò—v³åº™´r©c\–^ju7¢‹Cªºn޵‚–™ZפaŸìµ•¢y‡¢Y§‚N©¢yÄÉ^ð‡¸¿IŸ¨oǧ;¢êZ|¦__pCx‰H‹¶KAnXS#nv0–…7•µ_t†SXˆGmoCa–NB‰·bc”Xg€]X…gvh;¶·€½Qy£bŒ¦Ww]–—]}¼Q®hj˜7ºž>ˆè]už]‡eˆ¸I¤ˆ¥¸ƒt™Zg“tcu€º¢@Ý©‰Öÿ‘oån‡g…ââP•먶^}˜Lo‹VM„Dc€EÏ®4æò€ÿÿåªÿØ¥‰ÉËbÎõp¦Òs°¹jÿÿióÿÄâÿ†eË«t‰2a,r„-eŠSJtHr^Tk€DpR|tU{·d…{AµÄp‰Ó‚f«XTw>_y,š…B_­jRf3wiQ—Ãg¤¥hº·yZ}Rœšet gwˆC‰}MŽ›Nž˜jQt\ytM©¥U¼¿`¤´mx²]ceIµ’6™Sa†*bm.šžWd¨€ƒ—:Y DŽt=‰Œm¨RîÙ²‹çX~¼‚Dr*\x^hªH|[~µ\t~?qu~‚¶–Qn8§5z•LÝ—X½Ë^¾Õ†Óÿ©Þ£¬µ×ÿäÅæÐuÀll•V‡¹tedˆ–7pB‹B¡¸Q¦·n™jˆâ €‡eqzf©Š™‡…D¢X•Áƒ”QÍû…Š»D®áw—Ö…Ô’š¶Xg~?j˜8…=d±P§Ár‹ÁP¡ÆdªˆKÏÙvºîX¹ÛX|Þo’¬Dƒ±R™Áe›²S‘ÑMÈbª’†ÍÿĬÜoo°OfadZ’=œŽ{„¹tgŽ5™±`²áKr…F’¶T€«nxšM‡©R‡­mžª‹¨{z‰[d^[ŸŽœ®q ¼{¥Ïqcœ@o¡cyš^x”Bs’^ SY†OŽžKš`pvmz m±ùrr—~‡¥tn‘Bƒ£V†›Z`ŒX|¯ZtR˜£^v’y›´mY„Hˆ„sœ¯”d}@ƒ¶Îw€µKš¯cx§\yŠ=d{Q‡›ih‹bc‰Q\„JŠžarNiˆIeƒMd•Esˆk‘ž`|[ ¹sŒ²d†§\~œRsœQ|˜E…¡OgƒLcGrŽY€‘P_Ll~Xe[º^c‚EdŽ[{®Y„«cd†Mb‚3Ku1VtEd|>YsAnƒCw—7]|Yx˜a‚CZVlŽFw—Okƒ=e‡LawLfXg…X€ªV|›FU€Ks•Go˜`|•e‰£W…¢_Ž®WlŒYi•_…™Xx”p›²_qNp”Ha€\o…Rm‹aƒ\S`Ln0|b_ÕqVqQNƒ:mb7m4¥¤`o¥‡|“Uz{;lÀSu•<†”i‰—De†1³§ms´wk{Ÿ²™LèÓcz¹X™±bk¢^}–?t«€¤U¢«B¼ðkêW½ÌvÆpoq`šYÔ×fÊÿUay9†ŽT€°ia½obeIyŠF¥`\LJ|r~|žuÎu¡z8ÍåDÿÿÿÿ¾ÁÿœgC[m;—“^s°\nYBy³W™ˆ=€™›xu[³oq“¹g±œ¯œÏ­`‰?`nD{ŒEmŒS`…`bj+…¤=­´‡¬ØpsÌIˆ¢zz‚>w‚:€ªqŽ~Ff”LkuV–ÀM¡«—™»dƒ²‹‚¹`еq¼zr²Nu7”žI¿²fµ©ÿÿÈšÇNµäÂÐݱ¾à¸«Ç½[‡©¸wy°W¥©‹Âÿ¥¥Ù¨¸å¼¡v¸¿Á€´tjˆFºÛk¤àUª±y²âih‘Gw­Sz±‡‚¹Ym…`t®S€ÈZ„°h™ÃC¡³e‡¡jƒ™T†¬=„¨TxS˜¥xŒ«wqXl‰J±µY‚kx¦]}ˆCtŠB°ª}Ãtwš[† kÆÿ¸­ÏY¼Ú`•¬nºu°Ë}kRxxb“HgŒm£kn•R]€9b|VcŒcw›9‡^Œ²tw“]¥´€jž:_‡Hv”Oq‚Qt“D†¬cl>jIŽŸN|¡D_‚@dƒJd~Me’;kyS{ jwœ]‚©bˆ•Qq‘Mv˜Uh•KLr:X}9}‘OXr@j…5^H‘¤ž½W”³f|›_[[b‰^t›Fe{;]r@]|=ZDf„QcˆL`Xz¡tœµKSx:eŒue“s|­Il†f…”?n‚CYz1=a:GkJX€`hŽ{ƒ ~…¢v•¡oŸHt”Vc‰ly˜ƒ¦er“W†˜[k{Dt…GVx;axBZn:Um@]u@izBYy@Oo>UwWv–bw›n ^u“K‚QoUj•XgI`…La„8W€Rx›_^{B`}X•X„£gŽ®e•´~¤µdr˜PuR|•Pn‹Pe‡Wq‰Ga…QhKbSj]tŒF^‚@]Mg‰M[ƒh˜¹n†¡Kf”_š±Qw”[y›eƒ¥{•´wžµa•Lj–i‘ _po“ªgŽ«`«ÃJeRk}NeˆjŸe[gBOiAHh8MTBYX/Zp7OeHNiDVZ;Ph6Im=M_?P`<]c?Uo:qfAwŒMq†ds’aw‘VoŽ[jŠX}yEp‹T\WauOnl=mmL‘‚Jj›SddrO”F^ª`KrpnYAme+`†>¨nC¸y:ª{YotXXd[¥DKªUaˆƒTloBnoS]J^t?kwLU“^TpRup@…~2 –F§ªU†Æj^¼mX|chqWƒVx†Rs€QwnEn‹Trcl’[do[nILvRxb>m‘SXqjkKu‚8~‘NÃ’G‘Ísˆ•rpŒ`^ŠUkyRpHŽWe°]r…W•“G•¦l³¦xl¦wm‚Ua’S¦x;˜¼Z²°l¶¹^ªÔ…l׎‡„­J»Çn䘤±s‚¼ax¢^žMlãlRs†–X;€ª7‰—h§š_©±c±¤c{šq¥dsÉyw}Q‰’4Š¢RgŸ=mŠG_sOh8YI|}<~ŸAh’Š©›n§Ú‹™¸–qU«Hˆ|*ͬQšð¿¡¿]Â|i‹càŸAÛð\rïd§sˆ½›Ÿ® n·nŒ‘9†µIg¦„utn’Ub†Kt†9q€C‡‹Q´¶DÀÄQÂàsÆçƒ”û©a´²KqWpm l’Aiƒ7lƒ>_7YtG[h$g{$¡”M³Æ„ì¨QíÿÇ€ÿ»“‹it­K{›>YŠKy~[l´u{Y”•K†Æ[‰†Pš¥EXžy]i:Um2º'Òýƒví­–™XàÖˆ­ÿ½U¤„‘‰I‚¢y¢¼f­ÓÕtÌÆztƒb™TYd-|–1Q‡vP'¢‰DØÝÍšÿëb€‹v”@^?]?SuVB`*@R)ˆ‡a|šS[zF±g-yÔj€˜€ƒ°6 M³ƒš›|kÝ?¦ŸO„½€–£t——P¹”©–K›m¡¡‰‰°–y¨Vbš@£IФU™l|‰e‡ÆptÌ“Ãh‚ÂŽ„Ìc†³c“ººˆ¾Ži–_²‹4a©SbAvµ7¡CmžC¦{vmy9®ˆL¡Ðtyžgÿà”ÿÿÿäÿúÜÿ׳»RƒšXe’_ųD «l‚€Ko’“]EYudƒ§VgzK€P´¼qdˆPÌÆypp>‘ cƒ–cy”?‚„j¡¼c…²{~›f—¬O©§_«\ƒ³s©€>v Zqx:œ˜zÜÅ„ŠÛx’§T˜­{v­\›^tµn¬Z‰žT ¶²`¡RXlc]pt¦se{F]Žzp“_ha‚¢c̆€Œq«Á¬ä°psSk‘pd”^…©p~¼D«ÇÆj‡{¯ÚqÂÛ‘{—oÑUh‰?w·SlŠI€»`{©v‡­jŒË¶{€–e’¸—¶ey†_™‘:®Ÿ}k—^¬ÅTx–F¡¶œ‡·{«ªTŸ_x«]~…ju¹dkƒ_›ª€ŸÄ¦šÈ†Š|vŠeqƒIb”Pe†Ne}c]ˆ>y‘J’¢i|“F_w=`yDhyNˆ¬Qcx\d…S}©Jy›eƒ¥ViGxžAs‚Tb†Kƒ“Wi~Gx¤Ev“gsyDhˆF\‚BlŒDi‡CSk8d„Wf€Ps“^zžRs•Vk“VY‰L\yCe‰Av˜VUq4j{Fq•S{—osŽ|š¶v£¦ZdyCc€W]uDZm9hwFVp9`rFfyPcAjŽQeˆc¥»i^{2UzAW{bs”Dlsa[y9B_>Gb'E`+Jb1Gh7[{Zn]…©mr•jKfCLbCi„_e‰P`‚Tz“pXmR`vTh|J\uDa{Mfw7l€FuGl{PyŠ[|ŒMezKd„[d„Xe†TiŠXkˆVp“`{›`¨Zx›^‚§V‰®X‡¢Oc~6[vKr‡gŒ¬l¯v•ªp^yKg‚[mŒjŠLdGuŠRv‘T~œXiƒH\{AV{L]vHo–Ov Jg„Th‹tª¾wœ[—®s{ž\v“Tm‹\o™|“³˜¸g“¬Y‹ª{‘§bŽ™`„ o„¢nœ«Ne€MtKm_`[\qEPf@Qe>[]?Sm4IjCQR;E]5L_6[Z5Kx?ReERT8Rb7G[3LSCSd;oaMo‡]i‡fXŠU_z[neImq?O•\Nv[J`4fZ3Žo;|˜K`’kfwPbz?r€Ta„UdkF‡d.b•>q„U\{=UmMWbH6iATI.Wg#JiHGYFN_KT^?\l?wo=n‹M[ˆbfyJ‚Cl§T¢Šc‹·yXµ˜PraSg:ciCbK»†SŒ—Tbšs\‰]hmTRxV:bG:[9M,ƒ0Q—r~eSŸ™Ež´g·v˜©‡©zŽŸfiŸZWsKPt;YmAIqQk8{‹1}‘Y{ƒEP€qbcCN…C‹q0¾«B¨â–«¯nŠÆ[£ŠdrPc†aËzGŠõŠŠ¬˜Ão®r¤ˆPƒº^OŠsk_>¨}1˜¨k° m”ÖgÖ–jžËm†ŽhmŒ^ƒ]£¨C—Âms¶mi‰Lª{_oÎPwƒHrš7^‰9‚{<’–9ͯƒ|ÆdoŽc‰‡x€¥P_œ{„–yÛ©dÅöš|Öž‡S°ÂxdÇœX‰Voo/e—Hb“Rn‹[€”0t @x”IfœFÞ{SoÄg›¢MkÔrwnheo\hbC_c„V©·oi©d“‚1çœJÇÿ~ŸÃP¡bv`‡yM¢4^¾GhlA§QÁ¯ž–í³·±qxÓ ˜QvÓjd3s}4oˆOš”m}¬rL…Pžc?YµQcg8_€.£–9ÒÓ€rÞÔ]“:¥€Y·È¨Ä§pbœZ—ˆLzÆS„gW[•ricV„u7X¡kVl=`vKP}?sz-œ¤\”Ào¡­p€›G‘rGœœ]cx=—“X\×= ƒ!Š·šˆšV{­>HT^n3š’nïrÍÿ’’Õz¶{£^Ž—U†ÀivŸc¥ŒMŒºlˆ©V‚›RŸbc°2a{JÀ?q¤l•†I‡ÛoŠ•c–®s¦Mž¥@Œ Cz™p ŽK§œg‹}2´î€{ˆt„z7žÔ§­—‘Žíb}‚:’yF¥‹Jƒ²|T‰@·o½ã§¤å³ÒǨ͚·ŠubŸmw~-fpqc—ŒI_vWˆƒO’v=|œgyxFw‘Df¥etƒbš®›\?ŠŠPލ`—›W°—Jª¸kz“VryG…§|“I²Pïʑ¦Mšÿƒn¥?…~\ÚõˆlÅeŒ´[–šT}šc´¯c¬Ø_d•M€­cX£T6O'\jAMdd¤Zdƒ3¶1c‡:˜ÂRa‚?Œµg|”Ur¡]«Ã™Œ³ar—D|«Iz¥Lw¥R€“O„§X¤í u¨~s”Mm koxC›¸všá‡o‹c„©V„¢q‹˜yUpWMl4gOe‹“…fyC¢ºufyT€O¯Õ­šŸs©Ê`ˆ¶\‰µ_‰—c”«^~J“¹U¨^’Ÿo–Âf”·f±[Ì­[ƒ›]¢Vn”Ad{Oz”Er„M™©mzYl‚8kŒ;„¯[—ªe£¿V`Žy†LSn6]{ImU{™Sh•TgNtƒ_\€BnŒ>WoU€‰Cct@VrX‚:X|?af7gm(S„BXg;\u;g~9V@HoFLdNs_S‘‹S|¢[b¢]‚n]uŽFZ’yVz[Th3Mi:gR2±w8‹K†¨~y«ba“\EpNoƒK—‡Bµns²›T›jR}:•i4k§Gjzhai@Žn)u—d¼‹e½ä£þÉÑÿ‘Ú£oX„}IÁžBÒêv×¼ˆ©d¹¯ZgÝ¥t{YŸ«\¤º~~±\•K˜p½ÉX—×mɯf‰Ü[ßZ¥ùv£Ý‰@Åt‹Rb¤¿IÃån˜ÙšÆÉ:žë_eÀ˜{ˆ2d›HU|/k`7…oGx—Y}”Zƒp£ÆP²ŸkŸ¨mŠ^…;c8~1Å´h˜è€wŽ^§tFy̬Mrc†lfX™WfXEž…I\³oZ}1jo*v€x|°‰ž¬w’·›™¦ri©z]‚Kzr/nšTw•EVŸmF]QyŒ$s½[h|8t«6¦‰,sÅ‹§}s…Õahžfprjquk[mNƒ„Ww€IiªX~~F€·W_Ž1wf:lnEiw;R‘AH\Da\4|³d¸ªX„ÀrV–OTu6Nu,^„D_‚EsAc}YgŽVf‰Qc…C`tTbˆMmŠKq‘Rk„FgDpŽS~’d~™WŠ­]c>a€Ed‡DUt6g|Aa†T{™LfGlUs—KsŠPf…MwQ„¡Tm‹Dw„S‡¡Rr|Hk‰ISi1]nGmŠAT|9wœR…°s‡¢p|—”cGZl6U\,?P4`iLdvbpoMƒmE•„M§’U«•S‰xR±a{tİ{—ŸwœªŒ©§wƒ^ŠyV|mLnlY€€²½¤ÊÖfzš]j’i|©l޳atŽVv’\~ªŠ¥Àk{¤v¤Œ¹vq@lTwHg‡ZrŠKsŠQx[~’NuS]_€‹AWwPt–}¾ôÌÞÿ¡ÁêÔú…©º}”ºry Om‰W~œN{œPuX~Œk‰¥—»r†›`‚•\|“Il‰\q˜f}¡TsŽLj‹MkˆPo’Uef6_n0_g;]|DUnKRcKJY>Xd2Ru2Uj>Oc9PcH]e>af5Lt?BdCKV6A[/NQ8[]/>xHKTIW[+_u-[wDO{INj;Wn4Yf6q_1v;…Sx¶dw—k}Xi™ke‰XYƒPVpEof?›w5k°Lh‘n~qC|”Cn¡VcwV[w>wx?fŽP]W\rAŽc=“•D†¡o|”p»nUz‚DZˆ_]q]d,h–?ws;vŒE€…EuŽuayªmU„gqj@Š}1f“H†vM‘œD€»ot•`rˆW|}YbOYqEpaVaˆn[t][qN>iLdv>RŠM‘h9‚•Og¡R‚vF]ž]FvFRuCYv-P|+zuI^žDc€=…xEObWTp+`d$wœ@Ÿv8[Ðr‚^/]~'«‡(VÊgZ\Sˆ­fw‹l­‡b•ßWpÌ3x……µšTlPp¡X|š@u¥,†•A‡¯=jLmŒ=T'¯a7yžL­£}““BP€9`w6U~4xd(i KuuYg¯E–šk¦õĉ³‹ßÁ¤m¸|ƒ™jiªN¿Š6‘Æ|ªZkqk½»d›ÿŠp•g”‚G”Ÿ¨·¥ox”“ Xk’0]ŒHÒ¶<Àí—Žï†Éº0~¾•FsH_o6x•/[‚I•QX‚9˜ª`²i”‘[¸åbwÓVH{=^o>y‚TV‡Qq’WgŠ:QnJ†yPŠÈoa7²ƒVd?^Š5¡H½“3uŽ5tv4¢•DwžP«Ÿ‚¡õOލJæÕ_‡„LL€E`f9dŠ]kcbƒOe‰8—µiº±w¹Á€ÊXv‹€g‘qŠ˜X–ä–cCz˜Gq¤OjL›¼œÁneˆ;dsBm”T»l¤©i…¤L„…=¡l‡ªMß§ftÂBx 5g•UfŠLˆ‚Ty„x—Lv¦Gsu¢§³„—À„dR{†L—¹b–³chh‡³dš¤|{ªP§°\ÇÍau»f‘•q¦¾fšºw’¬¨™Ì`n¢]œž‡xªTf|Gh‚NY:e‡LxRy™Nbz?ZsAp•cu‹[~¢Q ½m…Em‰@qˆD“–_—°U„¤RwŠNz‘buœdw–YiYušLa…Ahƒ?¡»X”³Zb‚Oy›RxˆEtŠEYy<_{Br‹Igp=^vJq€Hn‚R|œVˆœVuŠ^ƒŠU„œ_VwJSu4WyF`‡E}“IŠ£T–]”°Uc‚D^xYˆŸb‰§W¦cuYjŒZsOn’^‡ Ym’[x[q„8xZbc+d†-e9DqDQWÒÌM¤ôt~Ë}©‹^£ÏLd¨o¤˜>Ò±R˜ïx½·pŽÁ¦˜»WÇŽT§²bœ¬~šœeò?Œè“’–z™im‰auˆ[i•^\Žccf8–l?·”IyØs‰™‚µNsH[n+|ƒCR“;LHBŽY5w™j®q>Îð›pîIu6“m<’¶^~²®l©g‹›w®˜­UâÞa¶ÿº|®~4qˆFI€FMP!z†,y†3LvX?a)GS>[Ieƒ](y¹UStF}ŽL~´]`ª4¡€D“³_sÒiuŠ+}„[±|ZÄÛ œÇ]‡DpˆJWo9soCh”u^b?|—8f¸zlŽ/‡ªS˜±T±Ef@rvO‡t;‡†XuŽ2³T Á>’‹ŠŒ­m_ÇZaw)ŒÌEe“4P•Dff-cƒB¤š\f†j´”GW‚X‰{C…²Ÿqœa[—]QjhLs'›tH‰È³} f¹6lŠD]iKeX/™TtuKª^ìÂu¿ÿºÄÒ³–¡T\‘ZTg3[|D‡±2]`,ww^KcDnzCyggxˆ7Z‰f™¢Uk·ZRx1VsAHYDd aVR.eb2˜ jƒ‘lƒuH\@†G”‰F´àŒmÂ@“’Dn›5t—BQŠ=lL.­“’±ŸV~Õh¨aŸÏ‚ÅD`y8c‹Ej„Ldš5gpBÙ¨YáÿÌzºhnMr‘E_tœ–€{¤\½BY‹[s|g’‡|¤[Šªaq™xˆ¶b|«v‘‰~ ´Y¢¦mЧTx‹j^yr~ƒi^}lt›ZoŠM‚‘QYy7{is”?h‘9}P‰–UŸHhŒDŒ P–»Uc„Rž§ri†JT€H}Ty m•Tn£O–´aj—Iy R®ce„QkOŽ¡]ºÕ…ˆÃz”·d}ViˆFg~My‘Pb~FqCw„czELm<{“MYrUp‰Xq™\y†Qz•`{ LgŒ>D]0\wCUw=†žSxŠg’Ÿ]všPg}ErLs„]Š“Z[{Mr‡Im—Wu—`s—AeŠT|«^„ŸW¡XžTbŒz›·´“É’£³s—·hn‘K† G—ko™G®Å~ÔùlŽˆV¨€d»ŽSy”8aŒ=ЪcÓµríÆˆÿÆjɳc²¯pŰ»‚­À^žh‡’|­™‘£žï³·Þ§°ã°€Ã¯o¨“k•›l©}µÒ„½Ú”½~Íʯj‹ªs¨yŽªVnG’Š\†šdv…[z“˜g‰š[wN‚LŒŒ[yi”½ŠžÔµåœ­Ýš§Ãi|¦aˆ¼i‚žn…ž`bƒY¥q¯Åm¥VdƒGr‘Od[°‰¨Î€¼x“²]yšYwUlŽbŸkcxI_u£ÚkÒÅ€¢ö“Ù³„„÷|˜†k£K\†?WuNMq3S~?ƒc'…„Bnˆ?eƒTk‹Vˆ—Vq¥¨£c ËÔ¼oχx¸QŒ’_ˆ¨`¨ sÐ͇¢çŒÖÌ€›Ö“¡Äy¸·cÊÍQgä°}U‡¨s{«pM“sOnEt{D{Qf‘PxfF‡‘mX?TwNzc,j“@‚r=zŸz[†[{x1Ï©A­ÿ€UÈ¥hdJg”d‚z,m¢h’“‘yfoļa‰Oˆƒ[ˆ´jVŸ`M”.X_2N_%?h3GX"PY)om)jz)auD‰W‡²f”ÍnŸs‰¸z†Œ5¬ä˜˜Ùyt“Uq“IƒC˜®g}¦£Ÿ•bw¿iTo9Es1@a6¾`"ŒÝLV—=z+“AYºRZz_y„pdn@„ŠLtsYx“5‘ˆ`m´°ƒv>ž¨QɉЧI©­z­Ò{t¢kV~9pƒ8n†@a§[ŸœG\|Tkh5…¤TreNMuDUk*r_Mª™T|Ÿ‰ŠÏcš—oƒpH‰n5•¡^h kmcJ­¿hŒ¡Z‚Ù¦x`fœ]\_2ƒ[s¥put1OuBbj)Wp._€;gn;gxB~‚j†”dXz0]o>P\$vœ†ÆÈ@}ž<€žgx‹a¸™es‘?‹D£t5Š­bx•ƒš›{®ÚŽwÀ]L£NQg,£­wsÃSZ^P–zA…¾]eªiyÇJV‰=l‘7Kt7qx$ìÒbªæÊo’N’¢dV€9]~AvŽM¾n¤Ul´h“t ?ˆ®†¯ S©›^ºÌuµÁƒŒ¸Wj”Z’štˆ»]s‰Xœ”vŸ¦m»re‚sñÀó°àcŽªpšÅ¤u°u¦Îj‰”]ˆX„²c‡¡ef‚Wf†Q®Ï]’R‹”_e¥FjŠ=œ²^”Ð’¯n˜O–—Y|‘Q¡Š_·¶L˜®ox~I¬¼MWw5zŠOn†g’®W‹¨[|‘e„e|še­„¨ÊYu7^xJarJl}DªÉvƒ¡_­Ç^U]}Vrk‰©ƒ©²pl‡Jg[‚ƒ_¥»’ÀЊ‚¡m‰©Xq‹HŠJ|‹K‡›\f€QXmf”¬Jc~CbwRx‡TtšT\o@^€O»Ø}sUv”HlˆRÌèdf‘W¡´mƒ·W–“h¥ÅXޱQ­ào®ÑŠ–ÇY€­QzT~©es”PhŽP [k“[„”[Z‚iŒ¥cŠœQn–]hbY|Ku¡XcY²SŠ®yu˜T¢È·®ÓuwgU–ta…Al}8ŒoN©\¯•g¼°˜ÝÑÎÖvÝÀf¸³r¸«‹Äéžêÿ¸Û…¤ÛНÀ´ÿÚªÿÆªÖ©š¿ ‚¸´‰Ñ­o²šŒáÞØÌŸØÞŸàÚ† `v’[y”€§Às¾Àk¦¦PpŒ[… ]l|Wu•]tUˆŸ_˜—VƒŠRj‚h–¼v£Ï²ç–³Ñ°Ñr–­d¡fv”aw’L[…]Фˆ›¸|›Ãg~˜U„£Nu˜Wy¡~©“¶xµfuŒVq˜Oj…bt™w_xK]vJ_rEfrNUrNzbIn„JN‘aG`OL[@GU,OZ4hc*y|M™>QcLci=¦{F—Ë›ÿ¯wvÜ®x–=t@¥‰D²f¡œs¶±róµàÿ¢Ãå–„æpJ˜jˆkW–T€ŠJi™eŠh¤¢@¬Ã|t¿kh„^”—+dËR;sRF_*yr|y]JuB[i@np8s™*²¢NrѧMŠuFh={m$‹‹Tjošg_¼‹Lc=j]6i’U®JÇäv½Þ~vÔo¨dT»‚jsmgh,Fi5yp!y«c…+fˆ-iz0p2fvE€vKÉÈk€Ìg~Ÿn€še¦¡dƒÒr„‚R{Ãa€[7{Ô~u£nh5Œ†Jdw;±|4¯™Vëó>ÿØ`ŠBu…-†³›jsP©´JhÅPyn>šSq¢]~š`¡“K™¦;€}Z¡¨~| {†»qjR‘·n…°{aidi@€|Oq‰Kž–Y`‘BdiGKi?Uh*rsMgŽRe‹5jŒUat7s…Slm5«„JÁã~m¢K“[«FVxYœ?‹”^f{Zp‰DkrM¡}X•¶[¯¥X£·gh£7‚§O~„F‘{1Š’5¤¨X˜ÿixy@\”GŠ3e„Ou‰jƒ„fˆŒHÅŒ†lŠ:~‘vyLŽ—E’œVd‹Aq†i”_y´fˆ‰\vF—ËFÿö®V²§]})¢z_y¯fTƒ3“g…š\o Sd•C±·kÄñ¢n•Gb}<ŽÅZ}Åbq‹B‚›T‡”XƒˆSWv5w‡X„™clŸS…‰h¯¢¾ÙTu|ƒ —VwGÿÔ‘¸Çh›–TæÐa™¦€r…Zy¯@•‹sy”Šxš]‰•bœµZ§pLz‡n€Œcg„Lt¯e•¸Y–Á`x¦5™¸I†œ_¬O±ú“s±W p‘²…°t}ˆ@™fŸfŒ®t„ªLs€tE„£TbŠC‰dÎÀyuŠC“¡U¢´Lw¡E•°u—¨Y¡ÆM^nEuŒjœ®r®É„ºnOn1\Ao‘F™žsk‹ju…N‚¡J}‰H´€v˜f±È–Öÿ–¬Áf «i¤ÊgyUcy;dFo†Q•³[„µRsŸJWs=mT—¬}ªÅ‹z [j’S›µºÃðµp¢i’´t”¸ax•j¿ÔŽÃÙ‘¤Èž·×wŸ´k’½–Øò¨œËcz”Kwžda‰b©ÂMƒ¨=XtMƒ£V‡ NbzJyœ`¯gª¾Wn‚Vƒ—_“šV…“H\oŽŒt”£[˜In|ˆŠB}’Vr’cr~_kGy^„™]¶žQÿ¬bÿ¨]ÿjNÿr'TNhp8gy7ˆuBœT¦xb›o_Wg>j€2`p9jk?Šw5†—Q{ŸXl l‡{Tr„?nO}L ŽJ›©X¡j––cˆ­g`©m…zqjˆ9UsCs^B`…Ak‚ep“AT•w€lZŠMžªj—¬CW«itQã=·Û¯Šâªo´€d‘ox‚DŸ‰Ef³r‘nlgŽPos`a‚FU†<‰s0n’J…I|sD‹‰=Œ…P‚ [‰¢}g¢rl}G‡-u¹lv}F]z4Rt7±‘’ÎMz‘P‘vFpšT˜ˆQǸW¸¾£ÀäÁ‰ÞÒu°Qv†šy3޹yO£_™cG`¥T7blO>=hdn“c´¿[m¿œa]Nwv6ibWN"]…'P„;ju=_Ž5[y8yRgwSs{(“~3w“T‚}Xs•@DŠfXj0XxQ_p>ä†9Òÿƒ´î¤i¯AsGXR8]_8ce7lh:Z|'_´=kiL„?g|dg„?dJ3tn,‰{Hq‘ªeƒ^xR«ª^s·‘SW2X]0•‰M{Û…m‡AÚ”cx圙i—òTűMÎ骟õØ^˜G†ŠC‘¿T±ÑGŒßކ‹‚¿¡P¤µGjÍgKp0„d6tŽ[ˆ®„lšZdiD’Æ^‚Ïjuªfƒ©smª<„’2 •BÛ•xnr IWg+ztDdlJˆ:ž¿Po‡J„ª``^‡T‰6l€LgYj„•]š¿zcœMhn;jl:ch.’¿\‰‡IËÛKÅ©¤¤]˜y˜p¤l¡¡fƒ™Aa½MÀÄU°·|ž¸y•ÈKp‚=Zt1i}4`t0tƒKtPlƒS¸¯v`As~Mf–Sw€Xs’SGj<_z:|˜g‚ŠCe‹FevŠ‚–hx£1™sµtlšB•»In§pVp3Qt.CmHypM}ŠUˆc½´_ ½k¢ÇWQ~—Vk=ayLcz8iH‚ªY`}>š–M¥ª^¤©`rˆZ‰‡M„»e‚ƒN~‡q›³\{£_Œ–~vQ’ P‹–Pš¬Th—AfnA–«±Éh|±?p’Qwb„«SWj;vµp€€­o”r‡£ucgˆ¡mm­It’ac†Y”›ÁÎh€˜V•žc–±k‰œY…§MeuD•¨Sy’>jŠf±Òd¥Ý?g…S`yVryUªÂ|áÿz“Ê\`‚I€—b®ÕŒˆ¦|¢haŒ9eyD ªXžÄao?b}Aw‘g…”ZŸRr‰aZy]†¡€Žµƒ‹®x}¤t} U`E˜§[e‹Lx‘_„¦czžsr“N‹«h¨lp›edO]}Te q˜UnMh‡VpšSœm‚¯tÂÝvƒ¬fˆ³ps•j—´{¹ä—ªàVx™_¬Ñ|»æ‡¡Ìm´ã‘} G™¤X€ªW„¼ìux _hpS€}SspL„…Y‰¢R}­XŸm•²~Åe½I N{€LsjW§•j ³pŠš}Š¥™¥Ï¬P`zC]‡j†³ŽÄ® Ó…ƒ””µ¢ŸÄ¢ÌÒ‘¨Êi}šfx™]g”V×ã°œ¼Œ¼i†j˜¼q€ u¦º¡Ë銜»y˜ºŠ Át°Ðs•µaz”k¡±}¸¿o‡¤S‚«m…¥[}§o™Ã„¼|˜¿dc‰AWƒf€©Yp’Xn“hºm|ª^w’Xu•M\|NyˆEc‡Sm‡v¿z Ék”²[ƒœNp•]u•]ygGmJq€VœsHnŠIlw]d|Q`zVO|QJdIcb5bz5ezRcsPAPbPJ\p-\sEkgGXn4LoCO^BQc2_k6_r5L†@VmQb_>fp9qr?t€>bTdxZ^KiuUOzYYmWRf7KnHOe?M_,V]9jd.|…>iŽI€ˆV“ŽO‘­q kg·l|‹^Š—R¶©Qÿ™Zÿ«Yÿ|uÿk,´WHp;ƒ…ML–¹dm­u\†rqnSt…>‚‹Ht„Hy|G|ˆ:ŒNf€PŠwVƒ”M‹‡Sr‹[‰K€—Jj™nƒva¢–ed¾zt|h§AoŒGm`Q`r8]h1`vK’r7Ϧa¯²`œ¡nx¨mµ“N¬¿ƒ»fw²b¡€Œ¤€¬p“±t‰·Nh•moƒ_´ƒKs”=„ƒ[d˜EcˆWy3—>›š`±·q¤É_²™d–«^Ÿ]q¾wL‡Rƒp<\œ†^{fd€?€y.YœARi)IV#`+Ê¡FgâxmtT£ˆEà¹zÁý~×ëžÅü™¡ãƒ‘¸f~¡H,›hSE&o"„6š@¢¼c®¦W}¯Sª•oŒ›Pm™g‰Vs‹;s•]c‹g¦‰CÂˬ‰ç—¨°bgÀF”uV‰Ýž^ŒTbq4t}3£-}›Up¬/`šXS‘@Ap2‰S$XªmX…/‡€5“­D¦°l†¿’e–_Kq=vR0kuC…•?b…Dt’RvmJb`Yj-„mDlÀNÿ“FäÿöØå¸^¿Ž6qP/V#y?Ë`cµlŠy2]´sfz-_rI˜ŒDw›T¢©FÄ«UwtT^‹Soe2ž|H€šJ˜»r‹©^QtK{i8¶¯„¦ý{ŸÀRª ©³Ú‚šÉž«è~W€€si˜O{œ;uQ{ɘt«]pˆ7’RjœudŒV`€A®p4`”„e`|e‰VƒN4i•R™‘Ta¦=Šle£“jWºÙº¶Ï³³¨_–Ê‚ÍÄQÏG‹w1ák~Òž¡w;…WšU¢cáèe…·~ŠS–®;‰ŸG‘‡dbˆSa|9Fv7AB1]Ug|Gn‹T~˜Vk”Za€:^oE¬¶mœ¯}q³lWAVvA‹Ò‘®qz“>nÀLo¥I‡˜Mޱi|—K[p/ž™…{€CuE•nxŒG|˜j’rU½¹Mzª]y]ˆ°mhz.s“{‚§\j}Tp™qÍÔd¶Ð\—VUl/js5^h+eš%|¤NwŒ^’še¼Ó‘¦·ox—5uCnƒW~y7¤ŸNªŒW–L«½\°˜Wž™s{Lyˆ@…Ÿ\z²Ov~E‘šA“·T•Ђz¥f“½f‡—m¦©l®³t“²U|‚I­«bš¸o½t{˜e„«En–bp˜=n˜RmEA^/p‚F¹iŠ´Ju³X_yMk…Zp•fx›b¤§{Øó]„œfŽ­u€‰zŠ•TxP†£z“ºe¥ºX­Ñ‰ÿÿϾÊzwI…¨AuxÈÚÕ¯Õ™Jm@d‡Vc|[_…Md{H¥Ïk‚“U±ˆÖìg†xo‚r»²Ž•¾itšEƒJc|Œt!K¢X`\5wX2øEÅç\šÛƒpˆejxFj…N©ˆ=‹ØZ|•q{–H½¥W—Û¸º‹Ó{‚®|®§Bÿß=±ÿÊ‹ÓX†–_§”L±Ûƒl jZ“Yq0_{?Rm'¨w+ˆÆ?t¥M[£¼–‰¼Q~RXJ]}-vxEq‹ªÊy¨~z|K9Vjc"‹q6œ¥T¨ÎYp²VUzO‰rAo—q¶[Ìð¦}í˕“¡ÓœŸþŒ>^3Vff~Hm‡REdPŸm;Ù»snÿhTƒ<`x-€,´éˆŽÒ€Oe@©~;›³kfIž7ì3zÃO^jNon1¢¨M—Ç`|±µ°†Ï¿•¨óŸ°°³”ñ¾È¸¦‰¾yBzÓyž˜Óé»´¿³±³SÖ£M¬Å|³–Ds°\p™cdˆ9\Š8d^,el7£6ЧdŒ¡dV†Ay‰6¬µ@–ŠEjez€[…¯‡”»Œo¬UqqX“–W›ƒf¡cXxK[yt|p”˜WͪW§ŽC‚xD¡³X怤§o¬uZ{qBê±U¥ŒkŒ™j±I’·_¨–]}»d‡·h„™Xj H»Ñx©ì’pŠDPI_h`d…bb„Mš™j{ˆNv”U•Ë=~“F‘S†NiRzŽp‚©k†¡G„ŒLdŽ^msLuv¨Õ…Ú¢žÅizŸDhvL£sš§\‘Vˆ¢}¿ÍwšË„˜µŠ¡°”ÝÂtz |JhE`ng¨k‡¬Zz¢He”OfRœp§Xs’]”´{¥¼ehž(xƒ7™˜lo—fx¨R_xC_zCz›€uœsu‘T}Œdo‘IjzBgxEw‚Uœ±kž²alDvœS}®Tdˆg_Œec‘an’f‡ª^x¡exÜävg‚FUsr†§±³ç•s˜DŒ³lq™]†±ˆ´ët“‰c<\ƒDp gv˜—НœÄ…·Ð„œÄœƒ¢|t—eŽp† Y²¿Š»ì‰¥Úu\}g’^p’i]†flŽž´}ƒ¤n‘¯…‰®dxt€™]…¦‰Ž³x•XZeuŒjy¥]cŒMW}Mi”v޾}’³PVsKbnW`TaŽFhŠNs–h¹¿„›kq£p”Àc¡´g¯·k™Áoœ»’ɽÍñŽÁ}˜Ù±Úõ˜ Ë€•©o|¥x…²–±jmœ`j‡Spl~¨‚¥¶|”¸yµc€™ZЧlƒ¡Xp–p‰¨cx–Yp£lÀi†®^¦T˜¯R`‡fx™\xŒ_x™a|“Kd|Tv‘XmX0|v:k€NY†`WsVhjIjpEyJz’SqŒhgŠ`f|Tb{bWn_Iq\R[Dn]-o~:a~APLOfPWd8qg4L‹EWl]RuFwcTx„2Z‘XbrVkpA`wBZmI_{EclEmZ=lx?U{E_gX]xAVr>jo;i|IqzNg‡NoF_‚>juOwx@t’k€j‰˜YÓ­sÿ\ÿw4ÿ…Sÿh?òX5yS0]|n*DO4P`+Á­o¤‚dŸºY¬^v‹KqÚyv¤OkxB±³ri|FX¨EZƒ?\›HX}s\y†zv°Zz²k™©p—©^}x@ƒ¤0–¬HXh:Rl,sB‰šU]‹IuwoššÔòx˜Ée„¢Yˆ‘hvd}˜{˜žRˆ¯Gg{=b}C¤µ€\¬Rµº†“¯oz¿E‘²|mˆÃi|–k³‡‰»ˆx­h„²O“€t±ÃK´Ì\j 6fjVÆZªÍhr IEX7†‡x­ÔU™ÊZ‚¬s‡¥t’±‡gŽcrš]l‹^u’euEwŠ\d‰RqŽstœMj‚Tc€9gy9g†N™´cq•g±o‚¬e¥Ïx±ÂYa~HJrE]{EJ€/:RB_tGlŒUš¿Š¯ÝUn—CVzn¯Ð¸£ßGl^²cÈêùÿÿ´‡¬?Va8[{=aˆCGhPƒªh‘´‹³Ø…o—c£w—¼]¬m˜¬w”Ÿ…œ€z¥`hWnb”²L|‹Gd{Tl\}¡q^‡ZmoMdW—a||}©s‰¯j¥ÌSk‹c‘Âg‡¡T_ƒM„¨Xu¥`~«bªCh„IcƒLs›`†—I\ƒVg’z€Zt–w¦Çx–»‚§·p®´‡·È¡¼›¸â¥¥Å˜ÉïÀÎâ––¾Œ’¥Wp™c~®Œ£Óq‘µWv“Ns‡Z_€i~‘cpk€¬bh–e‡¡hz•[v’]oP[€Lax²rx˜l¼{¬Ük‡§Vj‰ZnƒQo‰Vn„HeLf„Wnj3}tGdRQ„dMjSRdAmb8p‡Bu—pz˜}g qUŠkJu`]ZKRoCnjD‘j7pšDuoWV…TWfJjk_šFLnG]Tb_6ot5oJXzT`[Nd]0Ur?R^JaQ@Pk3Ml@R^5Tm8sb<|Go„Lt“HhIm…=q‚L‹Qƒ›Zÿ”[ÿšPÿh0ÿ|6ÿkBÿb2jT-fpUa=žv=Ͷ@Îû„¥Üt´‰mXz’9u§^{:Ž{1`¡J€p;œ–=§Y¯JÏÖÇb‰öa¤C·tHx°`‰–Q¶¦6¬ëb·Ê‚¦îŠlÄ¢YuTzQ\|_‰3‰^+_ŠIr7ƒv]x‰QvqC˜s=†|b³¾xªÖŒS¢Rvilf‘i„MŠ£5æ›z{ÿo}—TŒ„8£Ã[—ÊvšÌ>u´]H8JPy^'H¡Igs.VpN’¥pQ‚tr}MÇ¡­f¡¹²:©©RhÁ•„i2W1ljgÿÞIˆ¡¢”k.q•\`y:VNFÅE޽M°ÜNÆ 6£³P­ÌAÐüˆèj©ÃkÁ‘X‚ŠaKVLP6dp1¼gÛÿʃÌs°Å—ƒšA²†I‰›yÿæ–®á¸uÅrt‰Ev†e‰r˜”Ky“SŽ‘9€›fÍ’‚Œ›Zd£C^€7{…-z¬wLxRhm9a™[p”A\n+Uv9bs0bƒKgp.·µ~ÝÛq£ä‘”ÔcÇÈ`yže«¯Cq‰gd’R|oSq`_wÃU[l)v’CjPjŽEV{0u|Ea€IhƒV~sDnŠ)\p7v TLŠ>„^a•2`„Jbw@n£q‘œ€“Èš¾¹‘š“ÆÒ}§¾iœÆq’jƒ·O޽P|‹Qx–UVF‡esŠG‡¡]Œ´J‚¶O£Ëhu‰Foš[–™i^t=n@–swŽUt¤>r‹Om’Ay–jsr€X ai‰M O›³u’·jgB{’K’¸zƒ–O…“w¯ÑhÃ×w­¬|¡¹iq´Do”Sx•fu‹hg„Ls‹aZyZªƒ¸†²EŽ¡\¨Ñ†Ž¦}w”D„¢>{f¦Ùáÿ™ƒ­9e‰E¥±Tk†Dm¤JSqA`„R|Uu‡BgŒJ”Xr”=_qdm:y;y›@s˜Kp†V{Xz§Xo˜]n†SaxCjtG~|FÿPÿ Sÿe5ÿo(ÿe8ÿa2R0€|F‡F¢V{£azXMcªtw‚leŠoEƒn>]VcO=tc:s”ZgœrgƒUyyTqˆQo‡\•‰LšÂQh±d}ƒh…‘_€’h dlŸf|}I{™l§˜fÄÆu¼ôqñ i‰qLGNIdFsb?”•8x·PÚ•Nÿª™µ—m£¡U­°@mÔ‡OŒƒwh=X¦Hk}Ig˜@eˆN’ˆGh¹Y^{WªvQ¸[¡Áh~¹sj“g^‡XlyMnEƒ=Ž©Dgžvo„g~ŠV­‰aÁÁX¸ÓyiƃMpoPg9|v1‡*¦ˆ?¼ŠZm¬]Œ˜v¿¹OŽÒ‘X‡`‚p4Û®R ü¡¦©w¼Ð~“꤮¶Œ›Únšc=‡9VW/ku/r—'•oUšËyn®r[„KrG”œd“¼š†ÉR€ž:œ¡C~¡„—šÂ¢m©Ò•Y²—eo=l—^‰œ7ª‹\ZÆV[Q.Љ=z¼atU’§fŸÔL“t•Bg˜Af…4t›=‹“\œ‹PŽ“l^¥T}…*k¾žnIDiO\JRzx7Pf)•S-]œ[»f+´ÞWÀÆy¥× Y¼o_x5DyBzd=£¥c°¼§dŒpDsI'A2j7%XŽNs6x“bƒEƆu²é ¡Ç{¼Í¹óϪšÿ²E{9tp%©PP·Gxr9ver™J_&‡H­ÚK²Ç}lí `Åý“Óÿq·î{Á ‰ÚكĔ^ƒÓs\…iØlÿÿÚåÔ§ÈÓ›Ÿã{¦çhŒ¼“›¶“¥»†‚¹gQxReŠXB\ 0]$`]&€O¡Œ”k¦mz|`ƒ‡Mp£RqÔ\À¬‹…v_¨@Vq5‹‰‡’œa}›M¶çzg¼NFkFN_2dŠS\YQ]n8q~Hgp=\zEdj6hŸUœ˜[Ty1`f8kq`mySwu.}e«š£Ÿžj¶®¨Þÿˆ‚¡CiŠ_‘¢Mz~F†º@ŽYŽ«ˆ‘ºg‹“dn™:\[M™a¾Åsn¹pUuB|pEe|=[y1‹ai¢U`xF|‰pM#dc*Y€At…Dc p~ Vr•@߸¤¥Áµ«Ë¡‘µFŽ—f¦Ç~`•D‚ hX‚B|f=dƒb€«wn’l¥ÏuŸÒo°v‰¤amŸZ–©d™³^p–@t’L©]dJm›Q`€A‚H©ae}VaFzŠ[~l›¯of‹<‘Y~ŽL†ŸE…‘[¡¬v„er’N|¤]œÁk¢ÝQšÌP[Š@s–Nf„1Jh1‚‹w­Àj†±p‹wk¡X‡”HƒœV³Ëow®Stžd…¦•\€U–¤O¥Ékk†iŽ¢}„“YÞú_€›MaSdsL‚~G•ChwJ_uBXsJb‹;l„S~”Fi”c¶Ùžx¨db{WUxKœ®‰”¶T—·XT~AšI_zKª—kŒ¿„‹À`€˜n—ž—Âí±Äâ«”»–­†wŸfn‡U޹K}«Qc„1Zy;_Š?b‡=UrNiw`m™y‹­€‹ªesi‰IZ{Hv©bfPY…NaF`H|žTzŸ`™«|¤¸…Éþ™Êvd†76J5[jRfzJmƒ[oŽqn‹ZTkSj|JF^Q_Kj‡Mk˜Z«Rušo³lŒ¡[E[|Nf„FeŽg»o‚«^wšauŒMG`Oug‰ž…Ÿ´ŸÌ˜²Õz©Á­Î’«Ò•’¨~—¯Œ£®{¢½m™½c¢Z†¡d{ mz¨p„¬oqMk‘_|²eˆ Wk”]w›^z“f’­o£pƒ´rœ^u•]pˆbƒ“XjŒQfˆKg~Ux]=t?iˆUVdSgP@a>JZ9U[2hl?mzXX…qc€n|mPƒG€®dZ©zQqdOiGLfFƒ„=„œWf¦onsmztHr—OjqŒX\Gq„H|w;ÿt>ÿ Nÿe7ÿg#ÿh1ÿf.‚J/s|@xqH‰ˆSe_v€Wu‡;l”hk|Zi~QH~R:[KRQ5|S*u‘Eršp‚žck”Wƒ…^ˆ’L‹¦M‚±g[¤vfg]vx5†ŽMX³]JriƒeDx“Wt‹j¦’g˜Ç€Zɱa„xzy=SW€u?œŒ.©»^˜Æƒ—Ãy¥»}€¿Œƒ¥f©­G¤Êe„Äžr±˜œ–HŽÌksÁz~škŸVˆ›Y”£hyn¨z7›j¤žW‰§b|[eŸ\?wVXa.¦n:›ÆPš¾zO¸Wk[?lv8u\¾©qsÞ’[€pqb2ê:¯ÿqŠ´ƒS«RxqO®ˆG[ÈZŽjzp§IvŽ[èD‘ö¨w‹|\ ‹y©´‚«Öty±|;‚\_V.€r2c’:nf-‰m5Ês¬·p‚ˆF‹H‰žov~€nŒ]®‹JŠÒR—½U³U¿’[’Ðl…³W^aqˆ9¸|[iSdj;r0j•Cª¨D¢Ã“ÈÜe·Ú{¹m”ŽEŽœQšÂj}½‹šmYw™an¡Xjˆ5ZœOGlGIX@re+XlD@9(J<{ubò˜H¬Æ§mEÿêwìã^²ËAt³Nc§@„i‹OqN¾”M„×3A†pF1cb@…~Mb˜Hœ¦F“¢–›¥ŠkÌrƒdBk£rˆšGëž-YŸ‡@fXdr'zƒ<•²GaÂvyŒ%mbE™¢zk–º£Zªñ°ÿõŲÿÅÿÕ…“ê’¼s†º­°_îßhßÿù‚Ӧ̊bŸÌfK•xwD·Ô`í¹áŸq™U‡^[lQ“5{†7o™R’—mg¿osƒL‚§jv©\yºn}‹0u’;jŸQg~+—‘C_=Udt¨•RpÛEH_/id)]ƒ3€}Fd©YmLfoHRKf_'}]u~Pi“:s4z°Zt…6f“@ªŽC•„`MŽO•uVäñÔ±þ±lz[”ž]ƒ™y¶j~Å1µœ‰ž¡wpŠBy‹aÊHm¢`tw¶ÃŽ£ÝKzt?ev]ajN¢™ZÄè|i«KfdDW`hu…O^Œ@sw?g»GšÄki¡Fz¤c„]Yxj‚^nŒNieuHW˜U\x`k8m„:rŒW•©„|ŽR`{4¼¨i™­g‘µZ©M–ÆlzesŠWt‰S`†[m|Sp—fRtZpŠ}¨Â‰wÂPh~Gr‰X°©©Óimix…X–¦h«¶‚£Äa•Fl•j¢²“âÿœ¿þlsFn‘?mƒK€¤jj‹=Ž´_®°•ÿÿý£ÌCž›;“E’€b”‡]šTJh8Tl`¦À‡}©Rvšp¦·}ºÓˆªÔ]Y€Og5_ƒcfoKoIbOšÀz§ÕHˆ´lÁï¨Úÿ™¤Êg’ªkŒƒŒ¬y‘–ZpL·ÚyØübªàrªä]išA”»xíÿ›ÎìXBV|Igck’vm„OН’ž´kšº]¡Æˆ‘µK}¤M|šm‘¸„ŸÁx…®gw¦xŠÁ„£ÊiSwQc„6d|8W€:IhGQzau’Yk’IOf?XrCWp;QwGQv>hŽPtž\p•jpŽiy¡^KaEgFoŠTt n–Êz¯b›­Y€˜8Vf8hy]—²m‰ p…ªƒœ»v”½´|‹®ƒ…”gv‘pˆ£es™ch”`mŸ~¬|‡¦qžcv–Vi‹Mgx‚²z†§W\‘ku¦elšixœc}™o„¨ag˜\xœVx`o^m‡^Ro…T]lGymBouVA}[JZI?\39\8BP.EO2eL6nqEU‰c{hV‚šB|²hc–shkfstBZŠG^xRY{;Vy=M9hc:f€6o€PgodQjSRm8Sf4So@HlFHhDKg7I\(JY'^a4jx7YŠOU}Qhb>jr8hjHJubfXY‚r/y’Io„^kvKp€B{Š[|}AÿtAÿ‰?ÿg1ÿg%ÿj+ÿ]-sH+nr8zq4aŠJgTy†D“‰Pl­gnvbLvARhQ_mDms@oz;z‡Bx’fd¥id‡du€ZyŠF_MXfZNbHwpB‚|1t–Fyœ_e]ckApx?M’[`qT{@x¸Š_Ÿ„}€Ju¤Oj“Ss‹7Y—^‡ƒh‹ºo©{…œzµf‹¢e„¬dv¨‹w§}•OšÅ}„½š™ªšgu„V•”N˜¬W¶[}œl’ŒOˆ–ií±^Ùÿ–{ï[‰^xp6¨¢e–Ë¢¤¼”Á`z¤WŠ•>³«e¾Î Þ¥džfž‘C´¾ˆ‹Ï¤n‡ž‚| S`~Dcs:yv@_}\‹‡Al o…‚M’–Rh¯dTT‚zG€£eYWzn:ž‹8r€PAiD?@)E5Ÿj¶šhÇžeaªo‰‹3’šU•®M€Ãu‘ F™«WÔ¼c^å¡„uay·U„}Lm°A“”Aмa‘YŒ¥I’ºL™•Vx¬[‹¡|~Êqu†CèVy¸]š¬JÊŒs¤ÿƒ„Ça|˜b™¯btËnœ2¾÷³š¸V¿œ6ýÿs©ÿqª¸G…鑌¶L¹¤R„¤Š¶ ‰f§g‹f6uÈW^hC|ZPпa”Ó¹~³µikCr{OwmKrŒGž¡Ig„RRx]NLb_s:zzAb ‰@T|.auE‚¬OVnVf©FWt8o’D_‹@£d­`m–Nw³soŽN}¢ll:y‹Um’FXuIk‚9{ª;€–eTsGTq>Z‚=Ž´?]˜=^pDu†W™›zuw²Ãƒ’›h–¦dšˆˆ™‰†œGlŒH™°}­Á§ÿÿ½š¢Oaƒ[ZyOŒsu•Y–§g„„ŸÔü°{•aµ g¯‚k’H•³WeQrŽ=`†A¡¹”£ÏyœÙe£’v›js Yk—h“¾HZ|Bh’Sw•es£fŒ­‹Íÿ–ªÜ‚¬Õ³½Ùœ§Ç~šÀy{§Zta´à€®Ì~·ÒÄÓð¥£Åš·¦Ï{°ØšÚü¸f•ReMjŒ.Hr4Ec*RtA\‰‰°||ª{Yˆ„ŽÀŽš·t¢µwv£gVc€«Te˜iŒ»—¼az—Oz¤e‡°zˆ§nuŽVc`Rw_s—NVv;UtOw‡To˜U}¡AWzKh’RcOgz[iSf†V¦Xg”fˆµgt­z‚¤`o’K]|=j„_v2_v?N}@MhBJc2P_-`V%^m/ju9tK_ŽMh~NVnDR\AQX>dZ5oz,„ClRo}Sn†E†]®†Lÿ¥_ÿ…Mÿj*ÿjÿr0ÿc2†N-dh*\r2cmH]{Qjv@}Xc§jxvz~|B„”Mq™Nq]p„Mb„OVkZQxQlFw­Bs˜XHtNeS6iu0j}D€uEs•G†‘Xˆ§e~œjW…[Oq^^hHp„1ZŽfl}x“Y‚•d‚´cv¤c‡žFy—Vm™Jx†gi‚edˆ\Z†`‡€8‡¯fˆµ{…¶`€­ptž†Ž•Œ —i½³bžõx…Ѻª{€¤kpŸb­’[ªÕfœå¢aÆ®ƒ’b~ªC~£Ai–[BênµÌ„gÖ~V{pƒlSÆ“o`©ˆ[n8cqKqUÌ™puе—€MY Ss\8bv5zAtŸJy‡]¾€Sœ®w`§aKb5xo.„@·ˆYžkª„I””Rv>ƒx?¡r,ÊâWÄ×tƒ¶eZVog/TNocC†‡Y~¦p¦Pl¡€K}€]*f©_rCƒG{¤U­”V­^̺f¶ó¥Œ­’‰“o¬¯†~Öªz±y”Ny»š—›e¬Áq“ºrm¥n_ˆIfi1bŠ|`Ž€§s‘¢¥yª¡ÿ殿ÿ˦ÿ¨»qdƒ^vo\¶±C›º—ɘOÚ÷ÔÃÿ¿šµx³ç£;–ÀdK)Va@|4qmD_iQ€Œ-\˜rŽ—&-²]„.'Z½‘\BZÚS‚{2†‹fŠPšªošN¬¡ƒÂÑ Ö÷¤ÉíξŒ{ÙòŠ­Ï’U|:ˆ§¹Ú­[”÷ˆ¡P­·™pvÿÐwŒ:a—lÝǸÿŸšFÿ¦b›Ru{\ª˜_¶ÌdÄão€ÔueU~™<½ÑL“àt_‚‹T[(t 1âˆ\~+Ve)›˜G¨ÓR{Ñd[h@kyM™¥Jv«|r‰=¡ƒˆf)Œ‰8§±{ƒ’7iâwa§\t›K„_I”Ù¦Sƒ‚auLa“[Z€>m Zr—8€G{žRv‡;“Ì“\xJmy>VxA`u.{‘9r—F½¥YÍÿâ‚°dŽ’uv†ošŒlo©VŒ½‚‚ƒBš´Tm‹Yr‘FIu2kŒ?’ª{Äó®ÌÕǕĨ¸n¢e¥´g~†B…yKra;rWr€Iƒ¡wH—D¦³Ij¢\w‘D­Ì`›Îbq BXu9Wp8Un=ƒXˆ£s›ÊwŒšd^pJ\„-hzK†®jœÉIoš]\„;l‚Oz¬D{p˜¯‚¯Zi€1j“QauoŽ„£ÝZ~ RgAga{—RQs7W€2Zl1K`5pl¼AN{4`jGsŽC’™d‹¢c€Œgµ»g ¼É¹jr˜\mŠ=o“l¶¿›±àŸ®Æ}„«M€ŽD©fiVjL‚’ir”Q¼`¿ÇM{ˆN—T‚Xa‚Z•¶cy•^‡¬ ˜±­ßöy½Ì²¾nk‡OlŠ_aƒEPi;€©^ršdy˜W[ub‡°y‡©stpfiV{Jƒ¡mÆòg›¹…šÒ„б}¶ÚÀÝîÿ‹‘¸‡•³Žw¡“zšRl™=ˆ–Vy¢G‹ÄDq’4a€<{”eƒ›ps˜gVY`~fLlDUob–®XŠ®wžÉV\…EH{`do…¡lƒªp~–[\~_{™WjW|¦]iŽA^u:UpFLfUazceyRc~9\nKYz=[N>Q8DN2AT4CS)BS1¸Ø­²ÖÀ‚Ü¥q—Vmt)¹´o|¢}o“uŒ‹Ws«_„£DnŒPml,zx6—œgË÷‘v˜`“·tÈÆ‚Æx›Î–‡ƒL¢•smM“®Z›cŒ¿rˆ¨i•G¤»}jaf|Rm‡€ºwv¢qttU`8[z7|R}Ÿa{™ZbgHY\.°ÊM|—kU¡F]r`¢P•Ÿ|ˆ[¢«]y†|´³Y–¦gžZ•±G†Ÿe®Û”p¨?cuW©¾™Þÿ›‰®{’¬Žs˜?ey@Op4Vs5u˜„•ÅZ}³Nc‰Yˆ®q|«Zx—Kš¹nl˜q„†¦ßÿ¦Èí¤—¿[WPW|k|•ŒÈñˆ‰°gl–Ht‘P^†>f’Jq§ZšÂ‘šÅ…‰ªLTvDdeEXgLp‚Er8VvAgˆKe†a€Ÿgt–£Èçj²Ky¬]޼lƒ·‡¶Ôo‡ªYšSXn=@iVr¯hy§MnŠIv‰Ib‡Ge}FZmH]tCUk@fˆ?f’LZsJ`…Le~NeZkr;Nvq¥¹OSmB\|BWƒHZMkŒm’±s†§Wv‘Df‹]€ˆD|¡c¡²{{¡b‚d›¯q‘Š§ã‘³ÀVjˆs¤·v‰®Xiz˜Âag~E\†@QrVzœatHQsK]Rkd–­i”YeL]rN`{bvˆce‰\H`H9TH9M5T‚UVs>M{@Ua@ˆb.Á…6ÿÿv_ÿd'ÿo#ÿˆ=ÿ{Pÿ[4N,V„]PfS]i9Rv;ol4Š8‡—C†„Gm£a‡ŒkŒ¥`z®yˆ˜‚{ƒlj„ZpuCd‹M…m–­a¸l«{udpM~W„˜Nd±tDjTLZB c3Ä®:ôªLœ¡`RI”y%†ÀMj©ooU‚‡5c©Qm†Uv„Fj‰S…ŽMw«V¬[]©M^|fMpH9g`@Y>{\/‰ŽFY›kW„L€uOl’DuuN”’Spµ_`šlS€Wyv> šLn±‰¡c’šQmªW`…Nlo@‘†9m²yY‡_m{=¯~3k˜PmwBšqD‘e³„D{¢ž˜‰Hœ”š¡f£ k¥¯Y‹²h‹e™ŽEŒM…ŸO²–MsÉWgŠagŠ@y„>‰³Sh†X–t?r`]q8kw9Ž;ƱTšÄn™Ä7r©?ymD˜ŒKv©X“s=’Œ=n±wj€5¡‰AW¡M˜u0…ÕdjS†~S|K€´i¯au–lt \|‰I¤LXQ_b;j€6EpQZ`5´z'£DW~LY{V=v9m[À²LÐã›Ïò–Íõ•ŒÔ‹DzeXN1ei9…iIm’a‹y6“UpŠq£ {”‘b Žf¨ŠU€:—`:ÎäŸËÿ”Òó¿žÌ‰¬°RØÍ\Ôÿ£ºñÒmoD¸P¨ÔYmÁT—m>ɦF¬F™¸ˆ¤l—ÆU޳ƒ…™UÿÁÐÂÿ˜ÊÔ—¦_¼’ÇgÒÒNÏüœ³ÙÑŸ¶Vg¢l¤šb©óÖ­‹Gf3²|KO8_ƒH|*‰x¾‡z¸TáÕlžõy‡BegL²“J^Ž|…AÃæ¨¨Åx¦d”“b–†LŸ€EŠw^}pYߊ[fxPmh6~J§”d•šY‘pM¯òŽ‚²pz”ZŠ\_xH’€^”¡|€:†rY™«S†¸~Œ‘By¨I˜¾ {›CUw:Oz0iy@œHt–Wa™J˜~^–´”ƒ„ra”{n a~|^›¼Q}†=§u?zrA~†>b‹@e_mœ_†=b¾\|“Y{•O™åš¤õ¸³¦–ZÃA››céÛ¥Åÿ冺€ˆ¦J‚™Wo”aŸ¦k’«x’Q|CJ–7‡šOv£SwŒKRl1gOe‚HPi1Ye>pŽ>«ÏkSz@|‹BO‡4On7amHi§[j‰<‚”fq«Gg„H’¨R›Feg;…z>r”\\€BcŠK¹¶i†•l—©j•½dQs=i9Tw.St4rn;Y|=y\r…E^~D´±N§È†Éµˆu¡\¶u‘³c´v˜ºŠ·i”Ã’·d‹ r‡d®d‰–p‡¬S”¬]¦§b¯žT§¶|£¾q|޶qq’vg€s·¿€u’Xzœ›‹Âj{•Vbˆcp‹S^u4[}2gŠ5b“\ް¡±Ýeµãqk…tzše‘c†¯pXŠL­Ê«¿âœ¾Þz‰¯—Ãç^«Ö£Æ„¸q¯ÓœŽ±q¿p•Êo¤Êu­Ø…¦Åkržq}¨l•·_…¦BkŠFpOš¤b›´†šÏ¦ãü¹æµÝp…®”¯ÍŽûû„ƒšLiƒ?a…hƒ±mdbbŽRkŠPt‡WYvFNnFPsS_{KjŒO}¤htš[аWe{9K^7@T2OoYˆª[Sk8KnEf’^’ªKk‚f{˜gk–h{¦Z}¨e{”Oz˜^l“h}¦{ªÌv}m€¥†ˆººßódŠœmq›u—Sc‹yˆ°kv’Q‡¶Xl‰Zad‰•Ce|Gk‡ObŠlxœq…SZ~Se}NWtWmƒPc‡OZ^GBX>oƒSXdElbH\LPX8[a6Dy>RaBDS3?Q1uI$_.hM—HY tbx^gvJv‚Gj›]Wˆ^ZuLQ`6c['Òh-ÿ^ÿiBÿf"ÿn"ÿŒ;ÿbÿfJC3bpCjlMT{8ko>‹u2 Gnš`™†Rl¥c¯~`¾Sh»±t}…nTpŠVV‡JUwV™zL¿œE¶êނ߭oœsЇY†¤T¡˜R„³ƒ_bA]?KG,Áf-o䕜‘’œNƒ©F²ƒ€¼wa¨gZ}B_€DKyFke:ir=pIƒŸ?ž\cWE€Y_a1mŽ9;’<6X"HS#2UGhX(`‡9ivCl„=b˜@cZˆrn¯a^Œ=`‡=nRrxHz—:Ž£nŒÄa‚¸Yd²YmoUv“E §O µn‡ŽU}zGˆoD˜†IÚZŸé vn„šb›hµŒa£ŠZ}‡i‹gRŸeF ´^ÇVÄÞsåz}QOSƒqO«§[bæ}ivD ›gȼ½†Ñ©”â”—Ãj•¼‡Ã›~¿«\›Œ„¼~“šx®{h‡¶t¬š_‹àpk®\…“K¦ŠcžÃk†ªr ‘Dƒ§boªeuŒ\p£WªCa–\ŠgA]‘^e„Ctq4˜&ˆKŸ“:Q}USU,jh#`˜4wa‘¥¦u¢šÃs€tµmBrL>pxE³?§Õbªdw6fj@wÃoƒ¶™LbXqwak~1ÅÊ›]”NfmG^CŒ¡W}µOnƒ]›©sq„ehvA†²V¡Kt¶qWd:Tk7dh7mƒ?©©—„¦@›»hl’[‹8TCBiOX}Mi›ey¢¡ÈˆŽ³ˆ¨etšŒ²Ð°Ê\mŽFR€v—GOqKa~Uy€N]qC^rEgo—:…–jgŒk‰‘G‰½~“®“€¡_n£lbvPs7´•T••e§§^ÃŒX„¦‡]Jxd;݃bjÚsfaoš<{qN ˜S—Ćdšoˆjc¦ aV”Cxp< ’@…’VbyJrŒ;T£K`w6‚‹Il‘fQ‘>”>1drÏ—AæÿµžÿȵP€F€±Ype:…Ÿ=Öª>«ô²¿§uŒ¿¦¹ÓŽ”‰^ÔèzÅáVñÿ¤}ÿë}‹X —]Ùÿ„Æÿ¶‚´ƒeƒK=}®Ž`J°“V¢Ís™Ý‹k¨=×¶jÏØ“Öœ‹´unšuKŽÞfš‘A}Zy¨c–uwÑ‘‘”KRdk¦¡a]8oa[·tuª«ýÀiÖÖuà„Û°XÅûš½Ç³Íá±´íÿζÿÑSˆC«|]Œi‰_=µÎ ×ì½Òï°zÀ‹îFɃuÎî ž¬Œ“g,³–wÒ…N¹±xÚD¢¬v£ãyî©•ûËbÐ^{xdŠˆr“[s‘2QpO†{X}ˆ2¡ž@v‘‡…ŸO|™^¦e]d=|:M‘Œfp‚M‘‘Qmrt—Ÿ@£à`ašP\ƒA{‰Y°¹soŠS¬M‚Ĉ–P¤~µE’°c‡½AŒ”AvÊJVÃ7^r)r‚Q œM[…OHf)›—F¿ßvr«Sº|f”/`2r—Z§~T_|Hb|Hޤ\QG Oj4€|[{™`l SJy'Re/f‡D{£FeC”¥dŽQh›AUz?lw>a‚[ƒIi…?uPrŸPn‰Kq¯a_–?[y=‰˜BpŒO†Ÿfm–K«Ä¨˜Öcªº|m“EƒŸH^|7”°bi„G_yGS|3¢xgŠOeˆ:b‚W‰½vm@§£¦^‹FÝÞs‘¬l¢ÀY~~Bu›b„«woœHV‚HŽ–xˆ¬H9Z-cwBGo*Gf+L?NO/GW4]S;Qa2B^?;N1@H&gH'xo%~8dZPwf\jE\x;rpLbˆJamWhl?twKaŒdqsSz„Ko‡R`‹d^yuojTf~UjƒWc{GF~PDfL;_;GJ0OY'hY/^c*c^4qd5{‡<…˜G“a{–fo•a}Y{›doˆVXyEÿc7ÿu(ÿc&ÿdÿjÿŠ5ÿeÿyQÿb/øE~V.__%{:}—Gl„\ƒo`‘šR“ªmŒ£ce•P^|\–kJ¸Kƒž›–{\ŽdXoS‰e7^”Weuo~Z„‡Pš¬k‰­li¬Œ}…\k—e‚SޝQo½pm›n`†bo}GÎKáã†×ÿ¼€ÿ¼u³ŒsŽ_{—RœF}®b}¦oc¡`ƒ}ox•KŒ§J¥bz®S£_‹·a‹¤eêºO–ÿ^À~³:ÔZ œ€ÆÁx¾è‰Û¬†·‚‡µW‹¤`v«|‚žb¡£Z’Äkd¡lpŒNu‹8r”Qy™jd‘s~;¦¦l‹”¢\”«Yg¤«e?Zl–ÓW“¤L~«TIs>~¡/^~6Tr'WŠ/aƒ]ÍÔ†ª‚n²pÍù¹Ãÿơߡ³ÍiªÏeˆ«uy`Jm>ޤp~¥7d¥;Iu7cnA‚ c‘¼WÒÜ›²ù›§­G¸Áeó[ù­i¼÷~¤³T×ÿ¸W‹|†r;Ý™Ÿ±šj̈[—Îo°§]ÿíQ‡‰Ji;p£”\l7ip,{©ŒiˆK’‡]ts3ŒPcŽ;x†^œ‹Vx²e{„0w¶jZw7‡adyVt“Ldr/Mt?HnHz|B}~Dg‚CŒ Ch¶:Êæ»LÚ~¬ËƒuF²U©ÿ¸£Md~[¦~@£Áb’y^’·|¢¯uvŽZm´Gb„8W‚Jf‡AYu5p8ew=jz5™²czšC[ˆHt€rtƒpv’GmQ‰¶eÎZˆO}€Obx8WkGbmEw“Q€zKfy>u|FbŒNmŠ<š§J•ål‹³ihªSL{“–ƒyœn|ls¤R‹·`бq[„KŠ»kyˆQh‡Gc”,eqbfzNIn5”Yˆ­ES>j…Om˜F|¨Teš>iŒD3R9OaXj8m€Q{•fe˜ZŒ¤Vn—]•¸^…±`hŒRŒ–}†±xƒ¥ƒ—ÁÒåÿ{˜qZxA˜Ëq¨Õ|œ¿t–®l„¤l½ƒ›Å¬Èqk—Ed‡}x£ZeŽlmœjw£o‡¬pyždw¢ScˆUjCz_‡©{Ï嘣Ìzi[b‹^vš\bŒGazNz”Ruu8dv@ZrUe‚>Yw<_qNs€RiŠfy˜r»|Œ¥]vDXtKe€RkŒQr‰]x‰G[~F]~Cb€Yn[o‡X{ŽVq“giNc†Zn‘ew•`q”axžb†¨}–²}œºd€¨`s‹Mb^mŽ`h]d‹dx¢fi”VrŽToM`ˆE_‰HXzGbˆI]xPi‡i‰ªZ~“Pj„T@Q3HT04T4>F6>M+PQ+eO/ba9OkGEZDRQ:f]5rp:b…O\]PfUXlEXn8^nDvvC]XofLmp=g‚OrrS[‹QTxg[lckkTvMqQhŠe]~[Qz^GfNE^:`R/]o4bf9^n4sdDwz:~’E—]y£g|¡z„^x—X{Œd|…\Yš\ÿfNÿr2ÿe'ÿh ÿq ÿ;ÿŽaÿwSÿg:ÿ[+ÿR.jU-h‰OaŽKu{JeG~qE~…N”‚\j‹Ukn]†n=p–Nxƒ{†ˆZ†ŒY”„]¤¤I¦nŒ o‚§Vi©Xs”b†T޳u…ªre°f‚]Š»Koºhd¢pswGˆœ9\«^„v^—u²¹š]Å•nLjˆD¤Qfµh“…‚‰®Ov—h‡F“OxŸv…—El¤vY‡]PsY±l1ªÍŒlâ·c˜QW˜SxtO’dŽ¥‰™º¯›ÆgÒ‡‡‚Q}­oЉ´Tž®e½ÂbvÜ{c‹O~€T{˜V±¬V~Øt‚ž[ÒƒE‰ÜŒ•Ÿ†f¶w„G˜§Co¼T“‡[—uDÊcx ŠdT[rW8A'C8__$Yi.esKmYSr4¤y+VÏwDbI‰e'Y¬G`yJY{AulPމTµ“OtwnmuUkr[‚a9V†4nJ2fb>wj‡rZUxZu\T¦¦MÃm„ ‡¶to”a–mršP’˜S|¶nf€d‰E`œMTl,s2t…7Mµ*ql.©£Q`¬‚pi;²šKnÛ}s{?‚zH§¢Mžªs‘än…¤ws§=‘wu”Zˆ”Tp“u¦ŒZ¾Â¾ý¡VÊÒ—uR]œj¸pE³­ØŽkÓÙ•£áµ¯°ou•dÉrI‘i—™q²ËD¡Ç’¤»Œ°Å“¥Uvzho7yxEk’YyA’©Bɼsàÿ¨ÿªlvIm“s£‡7~ÊYe”M{•2qÈ~`€]rˆl»¬’²ÕÂgÍyÓ¯r©¥g`¾„tÄ|h³Uo:}rexx‘jŸŽdx¯ÒŽŸÅq›¥ui†J|h9Š‹tšyDø±’–·…|`°N]&œ{@²›oŽSÐ’mÄ„i‘®…äÁ«Ý¼wÅ•Zºujs¿7‘•l¤uAƒ€Q•ªY‘…MwžG—”f™•EgkR^ˆ]w‘dc‘@mq5W€J]ŒHh|R`=££O„`t”K‹m=ªÕw¯®s’œ{me‹¥±Œ·›Åœ¬®ÌQ Àiãrˆ«T«©Vº•]²ð³•»_gº[ywY~”Wi´Jw†`V}%†¤\z¼6Zo5`n2{¤qŠ—x|€Ef{6^…Fnj9[i2•˜T‚®e†®s[f8Nv0fwB~…?šŒG“PlzFZf3ŽŒL]‘KLo4h|l‰Ÿly¤?_—ISj5Sl.t”YXoCw£Gi”XX}5m–RTl=l„eYoG—Áf•Ãv’¶Z˜SlˆFƒ“] Ez{AduUQ]FKlU/:R1;I-LG,EU%Oc1PX4Vd7mkAjeFncCYo?`qHalGarS`lFuv;uxCiŠV„vN`ƒPeXU]h7Tn?iUAd€GW}eTxWgeHŠqDn™T[oOvWWhOVe¯µ`•¢`™ÄTw‡I‘_SlqCÍ3UÁbb[0„YH”ŽUº`N;l™n|‹8x•HƒXpšX¬€B“³W© zh}Vº¥Ý~´ÐmËÿ¨×ЙˆÖR²–3ß‹2’ðr½¦QÅé‹Öœ®¡F‰®y°”L«’MÕŽD±·‡€ÂR·Ÿ_Œ¬‘l¬xf‡nTYh5q^1Þ¢yÎÿž¨êš‘°§n{yKc‹>w~Ql‘S¢¹ƒ§À†y“ϛaÀ®{«ÿ®½ÿҸМè·F¯§~ÇkÑô•Œÿ±¤­KnØLin޲NwNHj§QpuRs¸lrŠXj‰/†Œ[†·¡^~^b™Xƒ†9i´C`”WFc>c~2Nv?om>c‹6ž‰9Ÿbˆ•M•¥sjq6U2žoOqtA]b2n q—‹‡_§*a{;Yl4…Ÿa|s;cyGdvY‰§b…¢s{“>kœ4^€/p’Co™WZ~:X•6Pm1Vw8kz8}ž[^‘LW|9dŽ2[o3]z9UZBRtAOt8@T)Rm:¡ŒOm„QOk,Rp6dx6`p2Ni6v¤?u©Bˆ°R|™xx”|œge~X„žYT1i‡L‰™rÈû•”ºIY{JiNv¡Xe•>\‡lÒÌ•ÇÞ…`\€ S]|:n|1pŠ^Ž»dxŸVt—m^€Kb{M]‚:g€\“°qWAs¤\y”yvšEUzLft™¼yšÀ`u˜€Æ÷’›Ä`p‰Dv~H‚™Tv‹@m—W‰£k‚¨f†j|{„µec}Sk;jyHoŒz§µuj‹A‡›A\u3S‚>Yƒ^~°hnœKf’Vw£]ŒGW‚CpJ[„L‚ªp}¨cjˆYhŠYh‡?ir–·m‚³[¯kzMl|Epˆk«¼`…§y°Ån«|ªl˜[t‰YpJ]BRxI`„BTtIjˆIVzF]sNduViuBMhHeˆB\ySeƒL[}@YuKZ{?Tl7Eg8Mj8EkKTwm†ª~•²[s”`w›[oHZ~Ga‰Zoct™bjŽ`kšds\x©oˆ±r‚˜\eb|c¤l…žX“™TFS*=Y,=F3JJ)TR'Wc5WkCZhAWg@]Z@t`wd>n‹7a‹\ZWeyPTTdkPou2d…GòkN—ÃQÿŽÿ}Oÿ['ÿj ÿoÿŠ<ÿŒ_ÿoZÿV6ÿ=!ë<#^a'AuTJX8’W0k¨A–{`Ÿ8ž¯\z½hx‹ZnE‚‹He—W~}Q‡…Mv˜m¡HűHÑð ò瑺ÿÍnÖàs‘i‚¢_”®_´uË©sªì†{×¥™ªkƒÈPœ¼pzµ[X’__j4dwO‡_†e8—œ@s¸t“dmˆBq‰`TšY_uEG€BSZ’b… p¢H|ŠDŒªK‰±dm¦ež…YpÌr€Ue’Aa€sPkE`d;pm/^pBohhr…MEzIšL;¬›cwÀv³˜O©É…µ±c¯“w‡F\Ihz;¬4ŽÞ]b±abl8 1ݨPj³‰«hzn”jdzCˆv4hŽ8}u8r«c¢xZš‚YY{T€¢Ãlú䤸֖¢d“Ÿj‚SÿД~B°®Eª®f«º‰¤µ\ù´m«¶tࡆ‚D§¾e•‚NÏoªYj‡d~=…¤\´GYq3^x=…ªfhbÀARo.fƒ9l„wˆ¸fq4l“;z„BvM—­b Ë…Êtµz‹¸nˆ vzSb}Ry¢[W€7bl4_mGs€Vlz_ar=`€fLlTl€I…co†h¢Å¢­Ðjs—Gc€AlŒ=}§n·nwœeh”QZŒ;Y„HgD`‘Pq—nU|M…§tzªeh˜B`…GbŒPe‹[o‹m»å–™Ï‡•ÀPrŒDpHj’[†´q•½{šÐi‚®[o¦Lަkx™KiIt…EsSf}_–®u—¸h‘®Sc„=nJ^‘Sh’b‹ºly¥^y™[]‡Tf”It‘OoWn‹VxžgšGpL]x@Kp\lŒm•¬i£a›\€¥]|œz¦ixžm„¯ej†\^€af„SkŒKhz6ZrBi‰H^q;McD`m?XpNtŒGbfCZt;VsHa{L^€LVkJd„Ti‡K`I[o6Ng=Tk;NnHNhUY~fj‰dsYs˜už£G[yLa„PY~T^€T]|Ugƒck’g|£u‡©uv“cl’j}¢mmŒlvnˆ“YOH+RM*HQ/ET0SM-HW.HVCd`GicGb^Fqc={xHbˆd_kh[_FT^;UbAV]`„I·hH«ž@ÿ˜“ÿxJÿb&ÿf#ÿj#ÿˆ3ÿ‹aÿjVÿO1ÿ9¤H#Qs.RjT`k0zn5‚’KwŠcšJ§¬w{Ä”ƒŸ|Zšc_s^BsO]UM‹k2Ьb’¢`—¬cœ´•œ¯˜b±°o}¡u’`‰˜]‡£`‰ªmr¶[n˜|i‰iž…WŒÃb†¤‹i¬uP~sEu?Ig b`<ƒ{:ƒ¡dW®ˆiyh€„E\–d[ƒS]x>Tx7Pc/Tf*‹g1u»EŠ q‡µ\x©rS§`I‚iYsNx~Hu•K~wh9€_džRU…Jce'XpF7hMIM0Zk4^uNUx[Um;gsAT…9m`1ok8xw@ƒj@–˜g}¬m©9o—C‘xO”£M»¬tÿ dõ––—p‚›NÔ…9ãÈYóÅ”¤«žÿTŸ×‚ɹd²æ¡ÿ™_ü’©y?´°aÞw•·]‡²‚ª{R¢T…__p?Rp2dm&“v2fªikwWjvYªyU›—gK|$u³@–ˆ=½ÙK¤Ï|`ÂUj’?w„:¯Õ]pŒZÆq¨³œ«¹tŠT»ŠLÕÖ£‰Ë˜e¤XeF@REfa3Gi6^`0;m,˜„0ÂŽ‡¾q„“<–´i˜´’TwL¨¤Fµ³wŸâ[—à;”¸;}ÄWˆrw„¿|€†4”-š R‰¿njÚYœPlŸÉŠÖvdU€vG§ëž> ‘Äg5Ÿæ­s§mTd9nš5Ph›i¾¡>©îh|ª‚vŠÁ[{€y”¡„yžnx4c)‡?[ÄÎDNeorNëºg¬ä`dª3exFl+¡«?¦¦‡ÿ¿wþᱤŸhÍË[ÀôtºÖQ¬Òz]Žfim0N¤~Æ$Ÿÿ?X¾PŽ}r§£Ÿå›Þ÷¶X}@XGcR¡l|ª¬°uª»DÚÃq™“l¦qÏ—…úè“q7ÿ±‚¤\ ³]“­~¨–\”mŰw‚[ÿØ‘t¼z“…mŠ}]‚·xŽGrCb@®˜IÐ÷³^–7~‚GQW"~|Sh…3˜]|°kˆvŽ–Ddt6~z5Ìóq‰ÄN½§¢pÇWJ€:bžL=R)·…~ÿ…KUZSY@`eH\h9~Y@‡|MŠ‚QmlD•s­Ã¡ˆ²†ž®O°hœÑ]§öLµUb„0ar;tzM’¤Sƒf‡¢_¦Èt±ÙsŒ©e¶Í‡‡Ìdi–.pŸLaŒA}§<[‡9Yw9u™j“§Gy²Fs†:‡²QeƒAgŠK~°`^|9Yr1Ul7xŒUžÆ|^‰HbFl‚e]ˆ\`ƒE‹RawCu|De~M Ô~”Éiv®aަXf‡O¯_¨Ö^•£†•¸g³AsŒ^|®YuL|´Zz¬Lp“EɰOŸ¦`Џq’Ê€¾w{¸Us”c~¡r©Òy˜Â‡˜¼xy«WŒ¨a€°UœÖyw­IVx0Ix;u•e–ÂU—Ëby˜]¡ÏW~™To’€²Ð…†½Sq”I„‰n¬»qÀ¹{Öð©ÈÚš´Ù„½Õƒ…¤vŠ®m~˜e²Êa’e½·x”Ql{X„¥q¨ox™Gc}Ol“a¤kqh®n€˜Xp–iˆ§Z|–I_oF{‰\€¥{’ªSd„Lj‡BXx9^vP•kŒ¦ZuŽ_y©mzœ`q•CDcNe„IUy?g‹Tq˜^˜Âqzˆ;SmJ[‡Jjs+=T6TnF~ˆb“©PmƒOxŠT¢h“©UeˆDRgAZtTe‚Kb}MZr?\€?Ux?SqAMdGWoFInMc‚Ofiˆ—Tf…RtIWxIMl@RqKQtRl‹ir™lu—fqŽ]oly^_ƒbj\l”N]O,gO4^V/Q^TcIuA5G&WI$\l9?j6IR1\[4š~7y¢LqŽJM~IoX3ut-~z9’zA¥;ÈŠB­™]’˜Y½O«¿kŽbÿ‡eÇ娮hÕ¢oÃ¥_Ҝʴt«”Œ®©NÂÙj¶ÆØ±µ¹ê»‡¥cφDÖ݃«Ø“­Ûve¬mwyO“–Nb•[`:[uM—i2İSÂ_y†;˜F~–c¦nF}¯R™MŽóA£•^ŠÌ—n”kkŽU~ C°˜5œËw©cÈfˆ™J€‡=…”X“Dv—~žuežslŠ:Æ5¯ÿc¾l@w+ª_0x³s[[ ‘<¦¯—|µ{ˆ«EŽ{J©Ém§Ðk”䜻ô ¥¬ˆËÔ„ »sŽÃ>ÉVÿу³ö€r`L°N^v)À­;y­>rÆNd}%j]š{JÉÐxµ÷¥Á¸¡îitÉu`“-«…9Üÿ›¿Òh•e¢eR˜d‰oR¸¥u{}O}“PPi:ƒi+Œ°Wƒàr|Á2oŸC€–ÙÌž}s€t+yºgƒy°ßZƳ‰­¼¡ÿÿ¦ÿøÅ¾ÿ–r´ILr1@S2„JÝÿާψÂblŠK€’SŸ¶ny•[Pw@CGŠy#n—BîØtÃÅ‚ÛëŽl’Pˆ|všˆMÍÿºŒÄe¨•i–aŸtW¨Çt£µaÿ肜½³´°\ÿüÑc{p‘¥Qg‹NR}(Q{Lv„G‚„9„™\Ñxç|»\QZ)f?Íÿt²ÿft’^t}:p‡Fd{9Kh6Š}ަ­»bYmœM•DTjX¨‹>ŽÒP–à–[k*Yv(”š8hxIÌ N†m,ƒ}PfpB§«`ƒ­ZšÅy†¬u—Ás˜È‘¤Ï“”ÖRƒ¢>^:l•Bƒ©‰v“T‘µd¡Þ~µÑƒ‰»lˆÂv{¦o„¨tŒÃu¿jk~\’Ï‚j—Q‰Òm‡Ë~èóæšÌ_y TÀUi‡M[‚7Wo5bƒ3u–pšÅ‹­õ†n’X† se‰E_n8bv9d”LeˆE”ŸRvŸPlzmj–V^Do‘G…²yi‡“x~Ub‰By“ Ï[|•U¥²ne`„‹~u f€¢v¢Äom˜J‡”bi£j…pˆ°fjŒho”c]aw£h²|…¶bh›RJkZa€pYZ€ URq=—»r–Äg°Ó¤n‰i“½bmŽGd‡T}–\_‚.c†Gd{_yœfš¼”»Ê¤Èë…y˜m‹£s€§q‡¥guš€‡®fx›lµ¿€x¢JvˆSšZg…Gc†Ny¨GZ~QlŒ^pšqoblNh†YnŠ^˜™Ml‚LŽUYv¥¸Š»Èl„¤SfƒPo~IcŠ]oª^nœUq›Ur¦o~§Dbˆ@j}Ia„M~s§¶ow›o‰§TgNm’^x€9Mn:nŽ^€˜gŠˆY{•Ykt†ªynˆT_†CdwIn‚Oi‡Sv¡ZoOjŒGY}Q^ƒS^‹N^€AUoGX~Vv¢Zk†\rƒPWp;NhFZuA[yHZqOWwW`ZaŽZ`|Pn~\oˆTc‡cp˜c|™VeX3d\8gj7YdAP7R19WD"^>3NT/[Q8_q3LsAkY@uƒ5^Œ>N~KLf@VZ>J_AJc9C_7UN6Q^-Nh:Wf<_qA`sDb}ForLj}CjˆTk€PeƒTmqStvHu€ZkƒX‰tZw›Hu‘UˆƒY}—Nž‚kÿxVÿnDÿ^!ÿe"ÿr"ÿ„9ÿ‹fÿgOÿA'ÿ7‘6Y„,BuBPR(n_'L„;5dHWF;ox<~„Caš_bwR?rBTLASa$:Z.^P'Xt7Iu?[iFOxCRpLPs5SrBap.\;x|:e•br‹RV”7NjKqj,T–`i}_ƒ–7_NAw>_]0jv?yƒ_’av¬xD™gSPCojNd>Y_$[x7[xPJw>Ue5hp1€{.Ž…Fƒ el³Tcksˆ \™L~€K~ƒb„‰@p„Ž•ŸT¶¼vº™ïÿ©Š§¡§Žg‘Â~›¢p«¤ˆrÇdóvNÜÿ²÷“Ñ‚ŸéX‘—xzMø”T²ÿ¹–éPŸ°F꣹ædµ°JÿË_¤ÄI‘™›{Íx|hec}feoBË\|Æ~y8{Ãb½Ž<éà®|‡`v¤—£ŽƒÿÏ}ÿÿÿáÿý‹Ó~”§`z”NVv˜œR¤ŽfˆŒHMlJe|9awFc’L‹ÊR—°STm;ˆ™X–hz›KÑzQ›{7„†O怞@Úù©–ø‚Xr:]y>‡=Q[.¾Úƒïë·ÐÿލÓk·ÿv¯ê“–Í{u‡Ue‰cdcަ‹k~d”Êjx™j}›Q’?Jd3mwbWƒKl„B[z]Ÿ’ÚdÚë‡Éçn‚»kq}P¥\l“9€‘a£Ì‡Î|W…hmŠ]—À}š¹s]v1Yd3Vx/pœAgQ‘\Áfšª^¢Ãr€§Ž²W‡žF–¼Œ£{“Åup ‚†©PX~DZzQV:hYDUsm€AQˆNZtQXfCX^A\l;{kBhvMqW‰ŠNœˆkx•fRv­idÿ_?ÿe*ÿ\!ÿcÿo!ÿ…;ÿ‚bÿ[Iÿ=&ÿ8Ì<KZ%@`JTM0e_$:„ARWEcl,h‡Aq…@2K)JD$7)L&*7W'1S3jG$k2A‡FW_6Pq*MuBToAZr:zu-ƒ˜MU•AUx^g{I+‘KE?•“7‰³c„£nƒ\«œcjµ_~ŽXiA`†P–~EnžmF€}eW5{“1›¤Q¦¸r«ÃtƒÓ’t›od”]e“VnFz8hª_NwY_iT`mW‹†PŒ¤O_¹df†:p‚=hŸHQˆOVwKnuGw…A™—Ls¯mŠ’Q¸”<¡ÔjÂ…™hóa’¦‰ŒjÝÄxËÕ…®Ã|מSž†tŠn¢”g€²Z˜o\€EÆu?¨‡[•pt‡CžlOœxR}t^@^=2<+}J(_€Oq€W’™Z{±V¬lG8vTYA4Fhbvm*GzK9f?W““fd©SsrN¹ƒNŽ­o|hD¿xH¬ì|Uòqa‚9w}Ezt3©™:wìin€>b†RˆŒ?gwjbq=‰`;d–MU|,”|Q}œ‘~œKŒž>¤šOŸ¹ah|”iy-^ŠKo, ‘LvÒZg©NŸ„>ªÄªðι§¿Ž~½ˆ‡[gŒI?b(]oA>T4QEv€.dJp™Pv}L¸»ŽmÄžXt[faW{fSf¿Vž}7ÝêKŸã›‰R£½z‡Âˆ¥ÀOX€‡i¡:žœ:±Þ\–ÙÄ~ÂÄÁµRáÒ}ÿþ°ÿÿèÿ»–³û°‡Òp}z@^i4Œ†8c¼{¥™W‹ÁˆlЉ—7k§LL]4 ¥’£Æ˜ÌÚ¸¢¼œ}žq‚·Q| GuB{“N‡£m‹«v‘¿M}ª[†®…›Àc‘ÀJˆ³SpŽXºq ÔO[€<ˆ¢‚²ä‘«Åm‡‹yžwSkCv‘p›ª‘†±~¦²fs wÏ×j`š.Wƒ;UoB_ŽIu‰\bNfuTf†G\ˆ:gH”¿]y¯Rs—es’Sh…IIgGgŒOrIz¡IƒšgUŽ/gS†©Z|›gu¡o‹»wv˜g˜¨j{—g®ÎŠ¿â¤¸[TwOwŒl’upVŽSh‹Htbufš°z¯±a®x•¯aˆ¢Y~šY‘ [VzJˆ«Žƒ¯AVˆ@]€f„°T•ÆX‰¶EhŒ\ Àq«ÄyÈî¡Óÿ´á„¬×—‡¦Oyi±Ê|¬Öy‹¬hhš‹¹vÁ㈶ÖmX~_}¬‚…žSvœKN}Jk‡YcHa‚HV€CY€Tt’\u’s³Ë~ˆ’CirQ|“HpOo_…¡k•¼|¹Îqª[y’U`|PWnLhXo“cw˜[\ˆ[g‘`c…?RrQWzag=N\3Nf(Bb@fo;NhBQeWjƒS]{H]s;NsNZ‚Xr“Z‡ egŒ^t•dkeBdh^O5UUGDO7JK2_U1]m[[4yl/m7~†GJ”PXl^^U4Z_4[h8bi8ƒjC|sP„|Y¦€Z¥ªlz¯…ã–‚ÿvEÿc'ÿbÿd$ÿpÿ9ÿfÿWCÿ8ÿ>¿Xfx.J…ISW5ej(r€<˜‘B¶B‚¶q{®XP›V1sL)A,O0sdeˆB[ƒIWs>XtHYo9ct(m~9E…EMd:a[(]lFf}G=‰ZI\|8zW,rœEj’N€o7v›nË<{Ôz‘R.s©<€•OiˆHo2ŠŒ>€_š•[½ªXÆÑ›ºœšk…XqªTg‡;zˆP•Àd‡E{‡kgeÍ›E˜æ›Ž´va|jc¯*d¨:pŠ5wƒ/ΛCt¶q³Ðl¶åtkäsF^nÇw<žÿGm»8;V°ù»ÓÊ›˜Òµ‡ugмT‹½®¢zeÍ—|6x•f=a‡7<9SC5͈ZÒ°›‡••ÃÊÙ¢ƒ›€lu®Vh~%[ŽIji8s›ƒ}‰c¡Ÿfœ¬QqŸE²é{©Î|ŒTË’QzÖx…MŠ˜¤˜n¬n|ŒEÚ¢‘¾„аi¹ƒe¡Épv`6]p`‡µUwz4b©xutZ”Vz«J¶œgõ¨•ž[QaBU)_h;‘¤wºÓŠãüŒ¾ê™ðÿÑÿÿÿãÿ ¾Äzô՞̀{ÊY¯º[à²j¬¸²¦¸û†¨±Žoˆ:n¡9¹ndŸEd9mƒ_Œ‚WˆN†Íaƺm²TÖ㛾ÌsÌõŠ•ÙS’×kއW{^XV†'3_&ndB«Ä•¾ß•¥W­¿ÖúŸ§äp¢aq®Ouƒ_¹Ä¦nØ|xŒCˆ¸ZŒÆk•¿aÃü‹¸Û‰’Öci–:e~ThbARl0ozBoˆK‘Šaca@h|9}|^Z†=ÇË ‡±`˜Z Ø†fC‡”Lr¨mQk^XkF£W_™L©Èˆw­j]pXz¥W†›zŽÎ}¸Ö‰¥y„¼]Žœ¤ºu`“3|—Zx„lƒŽhPt9ŠÊtºÃ‰k‹DVx9rˆWtNw«i~§su¤Xu–ZŸÊsy­ˆ˜žfaœ;Im4ZtUkNg|HVpEXt9MwFc€[bŽio mz«~y ^lsMƒlN†ŠU{ YnŠbsw^^zDl{V‡[v¢bjœ~yyZU‡O\TSiOlZc’iptJ[wDZs>sr+[E8sN5O;DOR_&Pi4Rg;u_?hZ#s•Fz•PS™^Wm;YqOwu5†dw­—v‘vZ“d5rNRF2he'”—S‰Ôrƒ¾‚c”_`\y_ko[‹‚c“™‚¦¯tyÐiG•cMR=|^;c†]n}Be€1…L`¤]s;n„o€‹[Š”f‹[ˆO’[KlkyP4Fy4_PI‰M:…Kv©a­‘tЧy¥ng±m”§t¢m×]á–u¤Ë‡ž “Í­n¼gÇŠdÛ^º¯f™”`Œqr£`Sš“C™¤vˆ¬f˜ª\l¦F€ƒ7D~Wj:2ˆ…B¬¬hg£i@tL?U5gY\n+p*EFiO`KW}CM_M’ocŠg­fO±Ò{nµŽ‹¶J† a–’PÚ§€e¬qr1ŽDž‘YÈÈŒ“Ù¯¢PØÚV—­fix’RmL¸ŠIǺ„if¶n@ÿvO»ÿ¯ºyW¨Ac`7¥…XN†b“X.µµN‹ð­W¡bk‡S`l@}ew»reœU“‚>Ó“O…µy´±{âéÄ•ÿÑ}TÿÎXäíìÝpk¦]¡¦c‘ɹu—Uò¶jáÿ¹~ÃZS®vZhT€^dMD}°h¶—z‘·”^ƒKdI…fD”žXaJ{¤mÆzYæÞ»äœ˜t,u6~•OÖþŠ‘¥o{pD»±R|‰ox|8u(N°pYLVA>Ÿu5Št7T{H€vP‡ª[H”Ÿ\š–`ÿ½¯°à‘ P¹©k޵Db›H„ŽKr¤m뤇óÿ£íä‘úÿÿ£ÿÅ ¯t§Ù•œ¦wÖ²¡‰£iˆGŠW޲d¥»®²—„°Î‚”»Qª±š|´=s¹P}£`̼W›²•®a¤ÕfÄa˜®‡Õ¶¿¥¶Ÿx«§r{` «]ˆÊ=zºh‹µe£Tëú´ŽÀ{£ª‚¶¼Â‡¸sd§‰XZ7b“3g¡_xw~§iŒ»{’VUd›£‡j†~ïë¹¾îšXwWNP,V_'Gf%nlw˜Uy{J’ÃMcgIypWhu=޵lUb]OWKŠ‘bl~w¦jRp;Ql3Sn9]†Ba‹Is›[r‹_eU¡ÁWnœax–^PeEi”[Œ½|‚¤vµ_LuLeˆSRKw‡U»dš¹olW‹ŸY‚‹R°¬ux’bl`v•qŠƒ€›‚iˆQbk©eŸI„‘e‡±‰w¡KTzFYEaK\}E_‚6\B]Œexª—Ñõ±—·y‡£œ¯_t”U¢J_>]@Jl;i‹ZxŽ]–Xbq8f‰Ma‘ir’KTxGXvHY€LW|?^xc€Œb€™di‚Kl…YŒ¥v£¬d¤¼Uo‚Bl‘‚¤ÆyŠ¼Š‘Æ£ÈŒ°]w…[Š˜Tuœa} T{ŸGKcN_…jƒ›o|ŽZf€L]pARkF\pZdA‡W3ˆšmMzbZ•iWhpÿW\ÿrRÿa-ÿ\!ÿd ÿk$ÿƒ;ÿue©E>dF"ho6…rBŒSr­md‰kMz­T{žXq¦dy“L_­f|XŽ‘Gˆ¡pŽ P®\„¢bZ¤^LvRh[6\†9‚>HF:ƒ_-yžk~˜zM¨uIXXSL,lh0bv€—qY?.~J1p`G}k6Oj<_L+–i0y~=xwO~}[pŒ?”pS”¨[û‡]ÊÝ‘©’pÓnË´‹¬Û§¯„SÄi ‡_»geî¸_®¶€§d‹w`¥žfMÀf:C?‰L@«EŒ¼t{ˆndW2³a8T°aJgU€d+N›¹Š€Óÿèa½_©œmÁÞpu­vš¥@pªHŽœB‹¸<”´Thº¦µŠ‚–Äiÿÿc€ÿ¡z–N½½Sؽk´Þzÿ©BÇ彬顛¦c†©e‰âvÖØ…hÚtzrG|ˆ6p@n`'¢ŠZ¢jºéj}m‘‘¤‘Ñf·t<§I‰¥D½´RÐt·Â•å˜e¹¸R}‹>Y\4°q†zHŠŒE…„^{W¼šD¤À¥·²r¹}QÝÒh²þ¶Ýç¶ØêdÌÛp¢Ú~¬ªiÄÝ…yŸÆ–~•=Çå²ÚÌk‰avmO¢¼Ÿ‰™p™—?šˆS«¤n“±tpt‚kVFž{Y¢—^ŠmS_‰-¢`EŽ 9ijG¯e³¿Œi¦VsxAqz]k«bjˆP{•iž´kstEŠeeŸÆx}’m{¨X˜Ói¯Øˆw™D¹¾gªÎ`ƒÂsPtFÁ´UYs7h…4l <_rXµæožULs&Y‡Io†jssmyXb†9qˆ[n€Bd=qƒFzap…HqRy¢Ex«M~¡Us­ONh>K`2Rs*z™Mc}-b„?—·t•©xrª^x¨Ruye~¨Zg”JGdJšio†l`šI]hS]qDY‹@k’UmZ`“5l”M_~Nz€ƒv¦r\‹OаQ|µCpœQ†šYbŒMh˜aWƒ1Tz?e}L›§Qtt@cMgƒOt˜Vt©e[Ž5Us3[o9V|.On+Ae%Gc6MoAJe=Rm;ZrHBe/cŒPcŽSa‚E_sCTpCLc5Nn2SoB…¶€‹¬hh]w9|{UgoX€•i‡g`rD~•VrŒ`mOZqMahP_q`q‡Fo†No”]t—pi|Mj~Zyo^€0Ji>R{B[Ed‰IgŽ>h”Oˆ¼[s›u–¾Œ™¼_m—q^f1Ad7rT€ 0Ux)Ky=i€Ihn?}”Hg‚@\…Nb‡N[|RaˆPn•Tr™PSu2>_@XjFY„R}Uy‡OizV`rVhŠX`‚@f…m¢w¹ˆŒ¾™‹´or‹Ph„Oe…Sm‹Xgˆ`q†AfxIj[\rTYnEVsC^nBXt[€ŽHq†S^yJjŽYn]x¦~Âw ÀmƒšFWoH^y;MkFKjW[uY`‹ŠSXCWj–kA˜Iq»d}ž€“g}§bp‘el~J—jB½–P¬Éni²wvt€p?hL“‡N“¦Ru©j[ŒchsGet5_my¨Ug™o\yU}V:Œ1O‘XdQH‚~;zŸg—e;€¨Fzˆ~e|E–uG|‰T}}@r‚I˜D¡ 7yxE‡iSmr4…W9šl?¿x?NvzBvoBtvA”LsªZf|P€…C—œJʬh’íˆt­[vjL•gQÌE£šU r\™eމUŸ|\ª‹aŸƒiŠž`©Ÿq¬×uDÆq3>Eua"Kƒ96Z#bC'­>b©PY‰?N{+lh$;2tKp;#ˆFáŸLk­u}pQ‡CY,jH0ƒ¨K\}]n#Xw-Zˆ<}r5i‡X}z\aq6™m0ƒ—Œž§XºÂetÚ­r~Nh{GZZJ„dDw Š¢šP…µOÊ‹cÿɇÿÿ©•«›jx\‚@§­{w‰Q€O¬CÙˆk§<•šVbKÀrV½õ„¼qÉ¢OxÚ^Õ†2±Ñ”«ñbÅéfrÿLK2ZLFŒ_9MƒOez'g}NÔ™OŸÿ‘ƒÿ‡ª–J̻йó¶ÿê³¥ÿ{R…ugwGe‡XŸ7Ć;Èã›”Én|–L”¤w…ec“u@‡¸mçÂyº¸t­<|T©½Š˜–`ueŒ|p¿f‚†A¶Ù~Â¥…¡}eÄÿ©ÿÿjÃÒ¡e¥£‘’7–S”´u´Q•Ô~¥ÉxÍü¥ŠžVz©bÖ‰u½ nÚ°¥·Ç˜ÿÿÙëÿÎѪˆíÿ Š°•Œo™µyšÞ«Åæ®Ý”V’Hnm&eolŽ|C­·l¤ËsŽ}SÚïkrM—0‘Aÿë“gq5nÀb`f(y™VtoržwɃ§‚‘™Yd‹;ŒQˆ™bŽPÈe¯†^²û…‚f:bv@Ä¿`Îcp†K•ŠjŒuk䊰{¨mt´a•/œØ‡gx1l~fy H¥ÓxjE5KZ`*p|-\f7mRF‹†CjZEnz?šH\mA{y^¥Æ‚’¬Uk¢]n…S“D‚°Pj9Œ—{œ¬s¹Ój™³‹¨Çq »rŠ¥`l—UczJ]‹,jžASg@f|>pŠPBJ,kq8XdAazMe†E~»]w—UO~:ARK“žpt˜Y«âiw·R…§[Ÿ»Ž²[PgVFh6Jg7b{h~¦ot¢du¦XSNiŒhm”qzšKR~0Us-XrAOx4Cm&Aa,IiAXg:]tLmz5Rs2f…IV?Ls1<\(CW/DM0Xu2m•Uu¥jhŠUjVq›^kšGZƒ9YqBx”DaJqNrD|`h”Ut§Jt¨Ir„Gs€<^k:OmNb~IPzOo‡\U€Av‚J_ƒMPl.Fk4`r6R~>u„N^~Ko‘h¥¸krZ}œu¥~”½na€6]ƒ?i•Hl@lƒG|ŒN‚…If„<_oGa’UoPhƒFX}^‡¬jq¢fv‰V^v3OiEbF}ˆVz\w…Kl“:Vg2E[Kj…:YrATtfl’gfŠeh‡KS~>PqFcyJa‚Mn’VbxJ]lO|¢\i‡\Š´k¶R|‚J]wRo|RipBSkGTxVz†SVzeeƒgt\my@MoQbŠI[v5AW?YuWoš’x}QZ€LT‰[{hR†k=tœYk’lf‹T‡W‘›X~¬c°‰]bnnCt{GzŒX‹€N}™JS¤}axvmL~‘S›€t‹cwˆ^Iu‰`_„obw`muB†o>‹ŽAxŸTrlmŠi^]krJSl>^hCvi:…P‹“]’—ld©hsigqg@ll=`yC^iE`o7ÿZ*ÿb'ÿ[!ÿ` ÿb#ÿh#ÿ|5ÿf]‘Z5†™>M’U)_RQ:!Ld\sIey6‘„L~Àe|¥|Ž•cwÄka£qk†Unˆ9M§[8wcMI9LS(TS/ce)]vAax@xo2yŽA^V[qE\^Chm:b|6ŠzVn¢ghŒVtyHXzD{i7o‘Bk†Me‰bQƒËK@wG†dP±lG« Z±S³±rĘXò—d¿Óƒ’‚oqE½uJ|Ø“½fÆùa^Ãw}‰kzFb›b‹cL¯h€“V˜°P°´m›ßuI¦ƒOR2ocH³zBkºs†KŠ´ŒŸ¹tÇÑ”tòÂzƒJktI|W3”“8±Kÿ¡c¸Ï}Ÿ†Št\²šóˆtL{fA‡±OffmŒB™¢MÈö«ì¦˜›CáÌxÅÿ|¸ç¬´ù¨ÿØŒ•볫ánµèyÿ¤ÿÿÏÿÿÈ_ëŒ~ƒ9»”M”ݺjŽ6OŽ/V•^ˆwtÿ¯Ÿ×ÿ›˜ØY„£çã‚~ÿÉu£b‘‰;€¡tnuIÖvh|ä›™»‹ãÄ…yþ«€ƒCU~2Gp/owQ‚|V Á’j‘bx¥g´Œ[ž½D|‡C­žMw’U¡n]¤˜hd–bƒqy¶ó›Â“™ž½v`’Z€…P›¬mb“„yndŸS›£‡‰×œ™^‚^›•9’¹†Çÿ„´V¹Ž‚æ×´¤ôª‡Ãu…Nah*™©{ÃÙŠ¼õµˆ»­z§L¨Íl‘£Y“Çmyªs¢¥ÃÓª¼È©¢÷ey±P£¶\ÿ’‘u°;iDlu=c‡_o’Ef|9_tNyo}?»g®½u¢à`fwWˆ¢xmjAt…‰fXŽœ^Óý¬•¢mšÿž[d3x`I|’MŒ‚W\4Ô¢ëÓÿȰßh±´š¹u}„5¬½‡|Ë^q¹Jez8ŽÀWyµD“ŽFœ¹Hj“Jn}2pu>|nYQ`*{‹I–Â~sšdkw:_ˆMcI‡ q†´m{’j ‹{Ò÷¬—Ñc‹™raŽGˆ©nos?}ªB€¼h‘»pe<`hM€«k‡£ƒiZgyE—³M_vK{ˆ„{—x[§7?Y7cVz{u¤g•’^ZvWzži~‘]Kf4>a%Gf'DcCv¤m}¥e}«e~žREeO^sPQrPh|WdFVJ[{Fe€CeC{»CgJp“O^}9w€W_…CSnG‡µ@dƒ5Ze;l}Fe…;U„FOqETvCa|Ts‡]_„M`‹>byEtU‘œa¢—NhnEl…X{˜Ii™Vn£J^u@lƒY~‰H{VewFc|B{ˆS\ÿf.ÿW#ÿ_!ÿc&ÿg$ÿx1”cZ~d5_„NLi\.bOQ;0][;pG_Q.Ÿi0x¹V‹žzÀ¢Sqêk˜•a¥²L„Ì|h­sFKMT*e^%t€&w—NtŽX}Ap›Ts™Xd”O†lAr¡Kj‹T€xBl™Ss’ap•G‰ŠSw›?N‘RgbIœ^7]®K~rL¡i"€4 M–Ô{j¿}d“RoˆBywHc¡Om“Q¶‰XÒÍdŽç~ž¨h‚¹dsK†”K«’Z±s‡¡a{¡[jtI¨tLeW‚cD“O‰œ^°«Zðºq|¤ºÇ˜0£šXž€XštLÝcK ‹qt‹\š€<¯ƒ‚ЬdwŸq’¡i±‚VÕÑ[ë΀Üéw½¨jʬvÞÒqzÚas_Õ—Q· eÄ©k¸â‚ £yqŠOr]H–JǃkŽæ„j‰„U{]‰o6w­qfŽ?^’0ew$ÿ˜G‘æ¤o³lsgc‘=]ˆ@_ŒD]Ef†Lgh4m\f‰=UtBw”_ž˜np„K`u@iXdsJƒ‡\XvEUu7q‹hp‡TЇZ‰‡J‡G{Pa€UÏÉeiŠ`BV|5Hk9Mn8Oy;pƒIlŒF_ŠHj}<[w8avKmƒMžW~’WžOs}:^nMŒˆWxYx W‘cޱz|‹O^n?SkEd}Tu©Ve†Hr™Nb`t—bƒ¤t‰¥_›d… [}—Ho3Us;X€^{©Yl”U YdŽSYuZIr}Np‰S]wL_uGa€[wqx‘x_Šz†¡st¡gŠ¢Nh}FeyQv˜m™±g|w2JQ,?O@dkDlyD^}Y`€\jŽK`‹IexJRtGUdkkVixLI„`Ba]CM8OU:d`3dw7`‚UiUƒ~Xa‡cP…XtjFiŽHM’eYjUOm@\aHTd2WO9_c>[>YmSpeHYi;Jg=Q]5P_/f`:zG†™K‰Ÿ`j©hcˆctS™€Cj˜YbsVhrKhoA}YŠ‹L„—^azQTdZ|Y6w‡6„|Jÿo8ÿi.ÿXÿ_ ÿ_!ÿd&rt5M^QK\3IV.DG='^.77'5H+],Q@ shrŠL£‰h­ÀXh׊~‰w›•Vœ¸k­ÄŒŒÄ‚L°‚PfOzm(‰Œ0„°\‹¯q‚·djžbN‡^Ug=rn8‡P‘v…®d“©t»fd”`x]}‹Tuxl^k@›e3K°bHY^fB#±d;¤Óp¬ËœÓp²‹Ž‹n]«]jxUš‡Y¬¿bÂÄr²ÛœŸ×’tºf•›O˜¼jªmhœ¡g¡«uƒ£u„xBˆ|A£}L‡œ\w~{¡lQ|œz„~}€—1‹^ƒU†£W{LfXšdcjTY_6†a@exDtyIɇ>šÄv”“Ì}WÇV®¼PØØ~éÅ“¬¦ ¨²qu­ƒ¥…E¿±w•Ðy£¿`ЍU‹«Dœ—S—ÖbwªQo¯?`S)ƒ€=r¢bnƒb†”1ä•a”ÀÑ‘­o‰Ž_űUÅi˜…H…¢yf–Xnw2a‡M3t9PKˆ>“Íj£Åh_Šmz;q—T‹•S–®O~©b;wJ\_6Œ’1Qªs/G;k^©Y€“H‰‰ZXM¯] ½ŒºÎy‰¡b¿°}®ÙŸÌÈmžã°r{Ffx=^Š;m6wœYqœQ͉Z€ÔuÃÛs‡ªŠ¨°œyÕz³ÔT‡™y²tcŒ×z€qpÃR„ž6˜¡,ñ‰=‘Þxm¦:x¨U¹»:˜õj¸¹/Š˜[ˆ¤fgs:˜·P´cS˜Ã~©¯g™W|¡N„‹HV¡:OnKbe?‘Kb AŸNœŠƒ› oouW“mx²n–œeWŸTµyFdÂH“}Få¥kyÿ±ˆZs”Dx‡e©¥Mª¶a~t¿½mo°xˆ˜Vycˆ¹pkw_ ~lxÏŽ±·\Q§To~G®¿À¡¹Šž‡{w<…‚W¢¡`›½t…dCf>xb2ŠFžþ„Ùì’©øV¥¿]Öª½¤Øq¨ë¤}¨`êΠéÿÌšÂJÿÿ§°€˜ÿš¬î™­¦P‘¸”¬£d’k<ÔÆw¢¯Hº@cOit<˜¦“”ÂZt†0\g4Ÿ—Xy²a|[R\n3Lf1q¥6±Ž]Ýk‘f^tO£Ïst˜G¨·Š­àwŽÅyq½ai…A–À€Ml-sz[™¨jѱ¼´×Ÿ§êˆ®ì…­Ø·M„ˆqx±H’—dµÉgz‹Z[€=oDk`0gg=™¤Ocl_HlˆM†«d…¼ef„F=U :S1C_'\9šWsoJ©J8‚MXC±Á—„¤Ry‘€|‹PHu&y_AvG–ˆv£Ír³âvˆËY@‹(žn^”FlyDq–HžžibtVgoa™£ˆ¡¾šV9nm[?SR=W)BX+˜‘‹z‹SœJ¶e™¶Q­«—©â’ÂЃ|žf‹¸Q²Ü„¼ë›‰¸`|¯M€ŸT}±GVb{Le˜VdƒV “Wq“hsx†·…‹»lmŒUo–gj‚MTˆC^qRJh@k|EpŒ[ŠfnŒKMp/OhKnEb€;m‘MVh<>^6J\Gg‡,B^%B[,Uo.Ee+=e+JmAHf)AY1=Y(B\Q`…@a‡Fj‰@ahL_Xr‹^{¢x”´€ Æ‡™ºzy¯Q\ƒSi˜;Hj.sŒ…õê®íï‚bEp^Ç¼Ž„ mˆ³h†‘^w“^…·d•ÁƒšÅz~¨ZŠ»užÂp„¼p{«az¢MgBRƒ@dŽKfsSi€IU|Et›dpHSi9\l?pzSfu9Uv3ZpE‰ŠE\oFezPhKjvGkzOeu\f…W{Œb‰‹HŠV–W•~RypBi}Hfq6RiGY|Fk‹E`‡\‰ª´‹³|™¯~ˆ¡\m;QeC]ƒG^vM\{n˜¹hy˜v¬¾r‹¥a”AbxS]x[Œ›U{‡W‹MkqJdy\o‹fs˜iy’RMl]uar˜u”¸sv•\iˆV_|g}£sƒZJfnKX}YV‡tŠœbe}Wq‰Ski3w‡HuŽZža—‡pŒ_„¢Upœ\p˜\ZZFUKWJiM6e|9]€TjwPazK~xO~zJOŒgG^T_W4e^&e|>8aN>°“YÿÿjÀÿ»¯×ª©òy\kCS>‚‹1˜¶_„¨ƒ_‚q_j?\yCW«D\t8q”>\†Lˆ™;ŽÆfa¢N}Ž*d“ayhA¿‰tÊüg¶Êq¨Üm°Ù|ëˆWºÿÀ€^f•8“¨L¥ÜŒÉ‚G¡Þ‚¸b­OÊ­r¬¨‡iŠ`ކ7²¯HĸƺeŒ¬w|/{P/X†A©c(n–iЬ”Ÿ\w~Kr¨Ožœf°ªeŸÓ’~”L¶›[^L«‹3ÿœ{ž†n…âv¯Þxt¡V¨Á™y™au˜AŠEuhCsƒJ”L÷«mq€R_zRš¤Y‹’r~’žÁƒsŠe¶¼ƒq˜Aµ‘T©¾}€”Z^]Ž€Q±‘rumEÁ¡xhV“x޳oGj+8?v@VÀ½ŸœÌ¨½ÂÈÆLj*|9¥à‡rœXžÝ‹ž«_ÈJ¥ ~»{ZÿØ¢­´ÀåÁW›©q‹|6p‡l•P‡­Á?b0g„LU‡PM_:_~BtˆIx©:—L™†w|P¤¶|¦ÇLeœ5yƒloXe­.[c3zƒPMdvau–OokFes2Of7d‚:N^Gz—OZs/G]3_ƒXk‡T]vHep+=R/Ed%NoCw‡Kb„9>b3@J4L\0G]2CY%@]$?a*;^Em-Nx?]~b–^k‡;8U'Ka4lŠv}˜^޵mQpDg‹UŸÀÕGZlgqƒz½ÇÍÁÓhš¿o”¸……¶xx™awŸaˆ¼”Æ|Nz]^tU~¤w–ÍŒ‘¬e‚­jn›h²mÄq„µPV}5k4B`p‡MoˆKi”yq¡pq–s…ªmx¥eoŸf€“>GQDpˆAg|;]yj‘°f˜¸‡²Öu£¡mˆ—^wYydj‡c’aƒœZ|\‚ªr¨b{‘a’CR}hµq‹›r•¨g£Mg~HHlkŒ§s|•anOsWn¡[jŸhz—VhxKc{Nkg5nvAs‚_d•cˆg£ˆO§³_{Äa¤…_†jGrUQTCkT-`}8P|RY_G]d4ehDxo>j‡PatYak>jn.W†GV|Ijk;c|={‚V’Qo•Y‚…Tw‹Gu`ttNizKm~N|~M]”NX}^_rCfo:vu<†‡Cb V<’jIZEJ/DY(ƒ_2†œt€?|…8šJeŒdL«£a€´t³¡g~¸b¯˜V¤™lµ‰[¨­^…¤\Й_¤ñxÓv˜½fÏŸZÀëy¡Îo¡¹V“¤ˆ‰¸Œ³Äu{·gU€OecG‚E€´qŒ—U°–K¸­€£Ì‹~²‘m•Kx|yªqy™X D¬„{fjagXNŠyA—•c²ºV‚²n¢R¨Æw{ʆ¨`c’eaw7xk<†´@rªjxvav–@sŽV£šAÍs…›m€­eˆŸ`x€“¯`ˆ­¤lÀÀh‚ÓdnšX¹|L–¶¶ºI¾Ë™”¼‡lXÌUqv%lËIƒ–;ƒ·D˜¬k_¶¡½oN¬ËvšÉZœ¥mš¶c’—p^¥T\€5S].€r5’Ãgv˜cX…Am¡6‡`Dk«]^ÀHm”PO†T>yº%Ó«p®Ê‰ÇÎ~‰Ì’š¾w¢Îl—§mÒ?ÎéX‡Ø¼d§g–…J’ŽV{£†Š‰i˜›W[‚c¾o6 W[²ÿœ—Ž^g’fyIy‘=g„<—l"WeAhwR|oA¯¨k·Ä³¿¦c–·O—žy§€fµ»ƒžÑgÿ‡tÿÿÙË«¢½‘c¬¯vpŸ_‡ qlŠBŒ~C…\;^uLÕy€·™q¾—Q‹¾V0m€vo„7v j®~Yz¢F™Ÿ•¸Vñ£{i”—`‹ƒ;|ŸP„”I}…P™ŽGެx{’Jž•qqˆ?rt2‚¨CdKzžT¸›`˜‘J’¸PÑÏ©°ä¤s¿k—šfІRÉÈ{p¢R{‹u”ØF«ÿ™·KŠwJ°tŠ{Un„dz‹ONs"aY?BE‚nLŽšIc‰3]zMMk(vk6h}JtUu¥µt—É?³Ì}Æñ²½¾ŠkÛIpSw¤zw¢x…´|u®au¬PZzBb—c‰¸€bzt‹˜ƒ}•X]g+CU!K_6YsJvŽIjŒAl|EZq4TvFXxHƒYš¡l–”Gh}RZ~tg¼w˜­]v…FytBjl2eh=jzMugp‘lЉZŠ›i†µl‚²hz§ihŠ5MTJhŠPbŠHpm’°frŠw¦Ÿj€Ss‡m¼}¨°]}ŠekŠ`hœ\g‰ax¦z§m—¨rˆŸ\y˜…”¬xxpx“a€“D_t2EhZc†inXdQlŽjvuŠÁiv“PQbCXrUVpNdtJ~‚K}©Vy˜rŽY„¢\r£ud{]‚dIrHgY;wv3b…@WxTgjIaq?]xDfpAblKiuKXxEe{F[€>\qBlt8n‡Bo”co’ed”^j‚hpwM„uK‚|Jy|TwˆZ|ŽR_’PF|eMX:cW5nl:˜~Gº›RqÀ”‡sp—HcŠUlp?mt6ÉyEÿ–TÿbF‘P&ks(^ƒ72{6$K1#.U*gdVh*5p:DO,Ca0D[/DBu?1ƒ‰hh¢sC_6XEgJ ‰Œ-§°\VÊlal[މD²«^iÌt`”‘E vvŽi]iCYp@efEj}I|‰Ho—Dn’Nx’Id¥LbyBŒƒG}³N] T‰ŠP—–>›‰Ve½Wk‘YxŠ5~”Fv˜e^‹P|I‘Žd•šS’yŽ¡j¡‡W]„¢Z‘‰b”´Z¡Ê}žË”—«†¢È¦Ñs¸â~Òœ³œoÐâx’Ò–oŒgmvCd:’‡:•»rˆ­…—§f¢ÇruÑ–„ˆSJ…N“g5‚Îpƒ¥€ƒ«h`~VQQ8xe8_=Ñ”6ÏûŽšõ‘‰Œgh±q²yrš»vœver@g:kƒXŽ<Š’lbDmO¼Ö[fÑ‹`Ot’>l€XjH{•W€viŠp™„R…Æ{a£h¯‹.Œ¯]w»dn…`…«KŒ T¬«n–µU»éq¡ß‹‡§cœÞ?}¥d¾{Pçkl\ŠNØ“M¸ìt¨Šné¦_ã·]ÔÑfmЊjw;“™;u™KyœAwŒA…¯]{„_lƒNa†Q‡•6ÁÕcªˆ|{i²¿fœ±„¨k¿Óc˜§k‹©gˆ¸‹€:‰Á_€²|Ù²\š™CƒœS€”M´·JñÿqŠÿ«œŸQw™o‘œWv‚Y›E¯¬Y©¹‰ŽÀp†”F¥ºuÁâ¤Óれº‰LŒ”‰È±w·vÿÿ‡Äìæ|‰XÒ>­¸[y¼}™šBTZ1px4Ž8ŒË{°s:rps”˜R»Ã’ª\ÿy;¨ªc˜ºl¦·z¬x³Ðb‚ªq¤³R¤½Z¿Y€¥O£‘F¤Ì‰˜¡nbk6 |˜»|›¬KYÅu«>Áǜϋ‡~2³´q’¶te”Tz8°’V£Âœé—Z©a~~=ÜÚ¡˜ëŠvv;ºÃÐÅáÑz”aǾtD¥.lr{ƒUzN‚´jqªxreS©¼~¸£Põ`°¹…§«Œ‹L|ƒSo†Hlv9^p?sy=kpcq­HpšVq•Kƒ«Pgy5Sf4v¥_¥Çˆ©á†–ØgZ‹ASgDhŠF`x5[y@V_EE_)TqFY~Dp Wt”XŠ·Sƒ¾T_ŒQ[˜3Oh:Bh0Tz@Nz9Ih9iIœ¯s`ŸGh¬]upb‘]f‡\nV_xTN‚OQqFoZ4}ƒ4l Qjgi{Vz€Qjed€icoJoHzuA„‚Ly’P†PD¥We¢ai~n\…Pl}UrrCy{PƒƒMlyOe€Se}QauGBqMJ\?ga.Wn1|\7¸vIƒËs–¡“—žjb®~Uy]Zp;–i@ÿ‘Fÿ‡V€O2jq0j‡EO‹K1vR/P/k9kƒ(cf>R„CM|JLr6Al6MX&]X'Tr,Dk;N\8{lNž•PK¨a)OOB/(`Q9n]7Y†@A\I5T3t<z(–²ssœjr›vç‰8Áêf î¨²©‚g¥Äj¯ËqsÍŒ„s§‡O|Šqzwk wL¡£O•¬Nb¸p‡€U|­Rf‡­nd ^s‰Z¡•9[¹j|xhv—QƒœJ¢„B‰½hjµ~š™P‰Ägn‘^WƒRer=r|GŸ‚Kš]¬ f§šHŒZ—•yf T…~G’¤f‘´yy¾ˆ¥šläàqpÿ¿¶{‚ã³T‹Ë… oxƒ¨]t­c‚¤V€±Hw`g‘qt‚R|šm´ V€³e°\ÀMpÌ„žš\¾Ëxa±}[{4ck1UJ\TWƒjk‹ ql’qpˆT‘|Li¢xxRc¨ZvfJyŸRª•U[®~hlLÌ©EŠý­s¬„¦¹L—À‡WÒ\Xf:Qi;]h/Ub;Yf4Lpg}T9{ˆL«©c†ÁpнH€—av«k“¶K¢¤T–æ~—Âs£hz‰LŽ}HÖ‹{‚µ|š£Vwˆ8Õ˜R±©³iYŒ‹p¸|HÆæj³þ£Þ¶\´Ízµ¤b—Ìuä´bx¿jd‡?pB‰ä=p w•—eŸ„X¼§r‰©u}€bs€?ÇUÒ…r~UnĆ}…@êÆOÛ´“çÿøuà­}¥M£‡Cò¤r§Öнà v“Vr‡B„”A¡º]ÂÕ«ÍhëÉ|ÿß®nž”Ï„E«ÿϸÿšm·T…«Oy~^æß{a¡DɪO°ßÚãòn³ÿg´ÄY«¬…zÿ«ÚBËÿj„™FÿâlÆÿÙ§î]›Ôb³Éˆó®ƒ–GÞ¦]¯­uxšjtƒQ¬‘¬WKTcB¡Š}m‰z‡”s`ƒK”fz¡²œ^b4B9"qYÁ¦ŒˆŒmj9}Ÿ²†—B™‹I¯ì}“®D®È‚ EÏîvµæ£¥ó¢¨Ñ~Ž©o¹te|½~i{Hsn5_ÂRzd>žºsP¨AuW|™>†§NЦ`JGBIK ]V,~pHˆ¢YQµ<@[ë«·¶û–gŽ)® Q€VN{ŽFiŸOhd5u¹-kw/¥Êé°‡†ÀJd`9Ìò—ªÿe]•-6h.J p~Z¢Ùxv¼Sfv8•`¬Ñ‘m±kYp\iF}paž©y­vb€¤IzvL²¡ewŽN`s5–§R©à[µáP†˜Vƒ‰X€¤[s¶V­¥…|ŸPÏòНÚÊ횘Äw]‘NGb5\b:U_IQzAQ^,>T!NZ4Vs7€ŒXŒ·r–ÌsÁaq¡SMm@Qe6Jd0Nn:^vJq˜`cˆ=‘­hc„Bd7e‹B€ª\rœDQp-Lb;i‡_X8Sz6u\šÙŽqŽEUf2@]*Uz;f—Td™]j‰T{”a‡£n‡«a lwœa€ŸOPw2Tp8pyPXsFx¦g\}DXt6Ln2c‡BŽÑ]É{šªZ­^[…AMs^v“w~ph~G:W.>W=RgI_eRk‚_y©max9ruOwˆV{t@jc5alSovLtwF]j¼r¤¼hw Wk—lˆhw’Ke}dz™ljw`y•b…‹[€’UnŒ^—…Pp„>qrGjvSzˆFvtGkoS`oQY{eq‹g‡¤jzœcs”w§¨xŒŒ[fyPe€[“£e ³r‡´s—·k†§SsŒOe†pp•t—Tg†Qr¨iz _zœNLdLd{DZN]q9Tf&4C.9O=UxM\…PY}ak“[h‹ooŽ‹­Ã|Ÿ¯QnV_^W€m>‰Jj¥_n‡yRŒUCpVM^<\b6Py=Pm5zc(†‰5r¡[lheˆc‹z]zšbwŒƒ[y]gjOuk:ˆxIv€U€{Xy‡Ex›Y`™g`l\[|JxxIqv@j{IkxPhKjwD_Omw?pAjy?{‚H^ƒ>wmCŽz@w—Zlu|{Zy“_wjY…H‚mEÿ•Kÿ®YfV>Tb0zf=ƒŠ<‰œVb®M“sLf±F…iO‡¡@‡µ\o®iR™ZWy@Šk(˜‘/“®cr²Xo{ThsK=n[@6G\9?ZtN.p-9ˆm0A0H:k["yN”—R­§q¸¯Zx­ƒMŒrj_‰Y•’j°pŒ©\®iPaEJXBsN:—rL‘«k•ªmh¥_[‚Z_eH‰`Hh›MŠR¹”;ÌÆ^ˆã`µp‚zOj•L[}Kf]PV|Nƒi7~‹Vf}Vj…IoƒFe†Až€IÏ´NÒ‘}ªmƒ†OizRŠ„@…Èj¿_š²k½»f÷‹’¬‡ÃÐl°ápËÆeqê®N¨ç}kÔ‰g{_“–Q}©aŸ©xmÜs™™RyÈQ€«daÌrÁ‚OÝâq¹ô‹·Ä€§Ùs{ªt_šSY9\j<\k'v+rAs”M‘ @²ÈY…Ñuy¢`q”NXŠJšfGWÃs©l2¹ÿƒŒÀ±©°~«É‹•˜£„è‘o¦f_ze»l3i“d|n>F”4rc dD’d7ÿ’MŒü£€™Bmˆ.Ä™a¶ÿ~•ͤ¾ h³}eCyZ?°{GÿÈPÆxzŒ[Â{E­‘~Ъ\õà”ÿÿ±ÒÿÝÒÿªÐÿ•ÕŽ™`­LÉÜ‚¡ùˆÿµFþÿ´ãÿ¾ÁƒV«É}šÍŸÞ‰ Ç]¡ijŸT|i)ˆvZx„Or©Tj™CŸ•G}›q¶‹fgÿ·Ww%–€#¬ð¨o¶w–ªr”«^¢¹O—²^µ¡u³Å…ÁÆ|ÛÛ“s¡S…»]ס` È“• Vˆ¹^ª’Mÿ¤læÿÑèÿuN¤ˆitE’Ts¶žåÂxÿÿöÉÿà ¥¡Î✪¡ƒæð »»–›â§~žaù™Rz¤m…”{íˆPs˜iÊ£X«ºUy}ho¦G›„KšlHsDxnN•´WÎÄHÖÕuh9`†kŸx?~²lŠotšwQ­¤I®—Ãߺ¡Þ{·´Bž¨pžŒ¦·´¦©£ˆ„bD|3–“Kƒv`Ÿ•o”<¯¶eˆ°M_o3žµŸÍÊw¼ìys§sw~S\Ÿ.J[*H<"GtóûÚ½ÿÅpˆ/•Çr¬Ä‡°ëŒ¡ll—¸TŠªy…`¯Nv“eå´f–µyÂè¾Îˆd~?ÊÿžëÿÙž§zŒ¾r‚“9{ªa_€kti?Yu6€­C¹gq¬U{“]”»\a¥>ˆ…]²×¥ðÿÆ[w‚MææpÞþ€™®Òܞ_|Df‡A‡¢f‹Æq¯±”¼fž¹”–Ø‚«udŽJx‚\V”&Mt4Tw.]€0[€+Vo-M\9|œv…®bp‹Nm‚^pžPOn:av?krLS^"Td6…¶Kp}sr¡Qu bUv@ƒ¡MxœOu£l‰±r©Jˆ¹i…Æb‡¼^x±VRuiž¦ hwERn31G"Smd‚>RwIr[j[c~]XtJn”^fŽIB_>QkVl…\[?Lq73P,ScQ’°Xn¢gu¯_…¼]²h‚ˆQnoXteAP[7CX5J_:Sns_wYYp^r˜V_‚bs‡ix“XiyKkMOxIi‡Xƒ”`‡Žb“§\w‚]ƒŽSlwRuŒXj}Mi}BcyNfŒF[€P^…Yc‹\rŽlvxbr•[y~@tˆcŠ—e‹¨rœ¼ˆµÙ—©Ðƒ”¶\d„IRpSsYi}K^}X}«o‘²Xdq4>a?QtCjJeq8HW+>^5N|Qr£]s¦qx™bv…RfyXbuvq‰^g‹Qc^X`Klh5mŠ@p‘Ydg8Q6_NGP+Ne&Oc)Ui-mb(‚2ƒ”Z}™fu™lxˆgWbdflRiR]YDhi8bj6vc=€tHqˆPnŒUO‘bLmVOe… d’§W€¿p§€‡Tq’V»t=…„G†{JŒ‘C—Mu~OQ‰QjcCr/…žNd“v«=é°cÄÿ¼aÚÈb…iV„>doCYy:€o4s<\rF}qQƒ›QW£|e€A¤wM…ÀpŽ…ubško~Lv†>}DŽ h±so³pŽ•S¥¿}¨Þ¯¹ÒŽ‰Û¦žˆƒ¾w¡_Ç»”vØŸo¥ao¤^T´s Ò~’騡´i] zFs~pV?uj8axUŽlCã’^†û‰‹ŽZ’¯]g¡yn‚9s…K€BØçXÌÿ¬Êêåÿ—Öý²Lô©ejD•Œ=£ÜbвUXÄ¢‘„isžj`‡j¸¡H‹ÿ«“¨q°¶zƒš|€ŸI[x[X7x‹Gy§P\‘E“<š›|¦Îe‚‹Z„’?s’‹_Ÿ_k˜^|–Qÿ¦JÓ猯§š toÂŽo‹XvCÿ‰eÃÏ^‚¨WžnС|羜‹ÿº†š~³Š·à‡ÀÞ‘ÿî©ÿõÉÿÿåÁÿñ¿ŠWßöŽÞº™Áš‹ÜÖl¥y×€JzÖ\guGa6gÒe\­[iˆ>m‰9~’QФ}^Ëh’,{«=b¢cXQrrC“Bz¢|ˆ‘ZjžDT§³µwPëñ”™Ù„KÆÉ˜ÛµP½™‘|SÖ”ZÿÆÃœÿË¹Ê‰Öø—O«Wf(‹²yíÑã¥Â‹ŸŽ;‹‰mJ~[Œq:µxLŸæqƒE¤÷[z¨jI`0ÆcNd¦QŒ±zŽ®S˜Çf‰ÃbŽÈh§ÿ¦j¡S|›*c¤:†QÄœn…¯‡}…0€¸¨itNp’YŸ¤W¢×Œ¨KZi7b^9cª9yPw§I‚£HrÅY\l+–‘Vv zW\8}j8Vb)X<@†’?Õq^Òôm±É{~‚Œ¢¤Jf{DÉÕ©µÞ›¤ÄTMV;B<6iWU—mb{ºz‘’W{µVŸ‰a}º_ÂUbb-mxHµvgr esv[Œ§|Úÿ¯¼¯vçÿ©·™©Åv’¨…¯²€t«Lq S‘©|jLwoHn YosX`ªIvkZ½ä¥p¬O…¤kœ¶c˜ØQœ®IÖà««Ý„]X6Q?hVQWs.}†jo–TÒ¹¿uÌRŒ¡x‹¤nÀmx·LH~.L_>ƒ¢\T…6j…O Ì`¦Ýe«?r7‹·T€’WkˆO_pOUhBVs2j‡I{”GŽŒC«µ€„¯q†¼uµvl–Rs¡U€²Zy¡dŒ©{˜­{”f…¯hx no£_oŸfw§N„‰Z_w0@^-JX6hNaŒ\…µR‘´d›Î†ƒÁWc}`…–_g‰Jf{†žÉ†{¯\gE_Sp™KbˆLdŒLs´Qb¨Mg¤EMw=EZ0DZ7Hf4;K1E[:TZM`|TbLd”BQ~O‹„^[xbƒ¶„ÀxlŽVˆ•U{ƒDerQ}ŽM{”OMx5ObG\n7MfBE^?Y|YuzWh[k€D^€Ek‚ar‹du`¬q ¨Sq„Q{‚R€œ_hpEn|CdˆI^šUc`}œ]u‘UdxXƒŽPRhPxœgœ¥\ªz¢£gˆ´zžÌ¢Óü­µÙ~‘»cqŽCVw]nNWk8PsP_•ff…EB]7i–ZjŒbƒPhy?a~Nz¤_„¢d}€’À‹˜°[omJ_pJ]ƒ_s›Uz’Mq‹R}jGˆ†4n Ge—U]UAGYaBTi0Hr5Lm9W]3R]iy@TkAX_Cs\6{x?z”eUŒnMskLa7]_3\k5fyF`„OjvE}wQl€DbYcWipNp{OexMteA€ˆ£AyY‡•Py¨Xx av—P’s˜¦Kz¦OY|V{t?w‚D‹xHxO’nS¤£K–É“¸~§ªŠ¾„x“”‘„P†¯rŠŽT¡U·ªd‚Ëce’fuUQyKc‹Mys@–ŒE…©jyƒUƒ{J†”n…¢†^¢qU€W:xD]K,k|3‚}Pš>©¿E§àeÕˆl–gµƒVhÎtou`„}M«EØÌVuò˜SŒW]i,I|IpU;­§F†ì†Ä™Ám„Æw‹µc{¤\~Z£•_vÖlœ_b’_zIÄÎn~É–uvf®Ÿ:SÍ{lR4jjChwD`lb·l<ÎÃjƒ«l]vORnP‰r@nd?¶€B·Î‰¸¼»Ý»·æõÌ¢þÚz£¤v„m†ˆ€äÎ^Ù¨š€v£`s¢Z^zL‰K¦ª˜µÂˆ¾´‚_°—µ>LwYle,’­IÀl²btŠX—xK–«YÀÅh†Àj­?“ˆKŸˆR…–^³¤>°ŸvÀ¹a”ÄTŒ±l·•I‡½S{–T{’qŽy=n‰_w}JöÌojÿ[¦<{m3Øé~ÄÕ¢“ªxÖ¨uÿÿ²Þÿü½è•å°‡Úî²”ÐÃlpwU›¢IyšNp•dxo6 ¸kg­`¬‘@£Ú·n–ku|Y§š]YxrDŒ¹I‘¯Yb‚m•z@z¾qƒ‰P‘ŠZÕ°ž½çb±h¾¹³„“y…¡Uѯf”g‡Zo’IÁ‘^¬Ön£}R~g~PŽjbx—K–˜FºÅ{¸~Ñ™lq…hq7{.•é^f•c¦—w°oIb€5ŸZ0¼—H¢šU¾ÅlŒ‹€‚¦—¯r‚«M Íc¼É“—Ò‹² l¤Þqµ†“{Yg8``?w´ZWŽPÌ~gÌï”yÿKgT˜xеrh†o¦®l¥Üs®ßhjIEl;i_7Ue/Xx:b‚ ×NËÈSÆ»‹¢‘–¨{]ih/Érc‡|„«¹Ÿ»Ï‚vªM?Fp[J­ |œYl‘`yao”_nFTj1DfBr™swšPOfBj„l–¼ak‹fpr˜kk‘V›•ISf(Xk@bZzXb€Ll…Oa…ep›c˜`zŸXpŸ\dˆLayKOlkX€—™±cyŠZаjްu‰ªkhŒF^sG_Gs}=jŽL\‰VXsMZuChvDmƒ@cˆFLK@V?BP.6M5YG2md'I‰Rkd_`qAb~Ttk>fƒ;\tHQ^D?`<`I0Wn*YyW\pSVyPZf?jh=yr5pVFŠ`F]F\L/ad/]mIfvUbgCfzIPrGPaAeb/sz5o”Pe˜Tp}Dh3Œt9v“Ou€a{@±w@‰§Y\ƒ|Ll[^ZBwqerK•2ž¹S¿‡Œ´–Z¡w‚sHh”V‹mN“€Cq£crqHŠ`NŸu^s7U|=Zk-®‚.§Ì…Ù•ˆÀw‰Ä€Šª|B©mjDšžM|ƒ~tr™‡…‹¬°ym£{VEYz9BWXjT(b^/Œ_=v]µ™LX¼‰»„_œ–m«¸L‰Ü`Xƒ\˜z3€™\„—t¶¯| Ù™my¬|‰^[œdˆ|AÊÅm˜Û©¯{O}\QjH±‹9xÓl•‚?Ž£s_Œ`wWCrlB³šCªÍ’µlŽ·„k…n]\_yi1›•G¦Ì_{®gvŒ>`vB_w7œ‡+n~^’z=ÿ–k«ë£š—…¯Àm“Ål—§`–°Sg g{–Qj”NÑtkõþ¶¸ÿÀèæ…Áõ“˜Ê©aŠR¸¦5ý–}ÐÿÒl°Ž°²UŸ¹k—ŒR¼¬d~¤SfO†¬L¨’G¨ý…±Œ•ƾ¸r§ËŠp®Pf”BzŒ2R¶}‘˜-ybÿ}m‚HuJ‘i²‰’ˆW‘“J£¦n¡¢aÿžX¬Î[“W€‹F¥{C¹•@o£Nh„;YtK~ƒ;=nFGU$GM$Q{* 5wšLºÿpw¯FJD¦Q¥¬j±ˆÆè•ÁÿY­ûl”¬iŽy¥ÀXz·`“­uΩkJ¢c~r/Àï²Ì†t®¯nŽ:¨¢1[œUñ‘[LÍvza;xcPšqB‘ªqNr=jb*›l^¼èª…žy‚`kcOiwC”’<°°S¾ÿ”z¯t\ˆ)‚ƒDb{4Š¢fÕÒ¥éü´m™qª€…UŽENe'Œ‹bÌžmÛ¤îÂzÿÿÍÔÿz¢ë]â§žŸÅ[{£LrA`9€dC®Wíÿ’Òµ±ÁÖ¹n°_Dc3db/´•_¦ŠQW°EQo7]ŠYj¡_uœDd‚m¼É™ÌioŸ?M[AP8ƒŸZe^n’Lsj}§K|‡X‚¦VrUd€W{ RUx;kkMŒ‰xj„A¯ÈˆzŒNm†MOs-Mk.Q}7S}Ls˜Ys¢Yp§Yr§h~ ……§aZkO^t@^v>Uk-F\*Nk5^Š15Q)8H2I\PtyKZn7SmA[{LLe:I`An‚|©§cMT?TrUdd}`nˆ;HU3Kc(>\,Pf3OjG^~Wb{?]mF\…Te‰N|Ak^‹­p´ry›z³Õ‡²Umˆl‹–s€ŽOTqGv‰Ng‹Nt‹X„‚Rz©m£¿£·ÙŒ®ÊtzJeYt¡znyQnt[v’Qj‹[jIuZ|¬{‰Ÿiv–Qg„=SwZpœcqŸex¥q†ªZi;Gh2@]?Cinklœls¢tušfvˆPismC5P@,@-6;(`?!]b%ArAO\JXd,PyDro?Qˆ==UFO;!k`(Us]jlO„yNyjlŸ[stD±‹>‚FŒ–a”EbŸWswH†z8ˆ˜Q}Tƒ‹\ŒKµ¯U´Ú‚†Éo¡žW·f’蟜’œ”H²²Q—Ði€½br­d ’`¢¼x]¸‡w…U D›žUyÌ`–«}‘\ž¤R’Ý[‘Êl§kp°C–~YÄ`¥ÐŽÈÏ…sê­Qsjgu.A}4OCÌQd´a±vA{Êbz“\v†0f…8©W“›VÒ¡\d“‰“u=p¬[«uo­Á\j•S¡•B_2_j=jg(Kd.JP,`VKn+€m;‘¸†q—cÂÁGƒ“ƒÂâ`qŽHXr@à€M£×¸ËºÜ¢Ü†ƒ¦q~­a_ŒGi™pYeJŠ”?”y­gu[Bd`3Ä•fš±QÿúÔH‡D‚?.y}C›„HÊRÿÿ‹¼éeŸ¬i‚q`³Nhs6œÉPe‡P”UÚè™âÿïS‘1Na%zy5‰´ZqžoIy@V{0qwKàÊMÄ]MHzˆF_vAa|Pd;Zv2’W‡´l•ÊušÏw>g;y”‹ÍÆÓÌk¦Ïš ç“æÿµ†ª{}À_”¾tÔÿ°žÄwŠÀW†½^Tˆ0OaCQ|)YwCŠ»o‹½j}­cm›s—Â|ŠÎasŸHIt6?R:‰‚kXiOXlLq™gp±Ew€Jp™T‚ªaj—H|©IZ~:RyHn–psŸT~zcUu=bƒZm¥:U5TjJ`‰Nl€]…£zˆ¾r‰ºXi•RTZ-L^1L_\5Km6G[Cn…Z²NzZwŠNl˜cƒ­g„¬d~”Ko}g‘[€—]p~f• €ŠY¡hl\k‡RhŒ[oVo]iŽ^tœv´×£÷þœˆ›y‡˜k‹¬Os‚J_pFYoIn€EPuZo…PŽWk€a„®‹¥xŠ€gkuIbx7M|Rqªlz¤qp†dgYZyI`Oa„b† rv’syŸ{œm‹†Y„…Fmj?bbR`žZP‚_OnQ\k@Qv7QrC=b>7S4:U*FN(AU61R,=E*bE!Q^+Ah@WV>ag&eŒ;LDYfHGh;[U:U+…> \ˆªix±jp²in¡ay—Ys‘Ta‚OO}QaeE^f5do7ayMX}VSvSk]>du5cN}yClšE`n`qT{n=Ÿw;ž•Gt—_r}Y…‡G²ŽP‘Áz]½–@‡ljY2ƒ.w‰M{—Xx•a…h‡˜Td£e^nElu9X†LioOrŠA{Mz”Ki™btˆd„^šŠ{´£g¯Ù §ß¶’Ë—Š¦lžE‡”Oš[c…IfzA[sPaiR…h7ušEg‹N§—B•²Gp¬fƒˆ]£ŠEz»`Š–M¢“c€žP{˜[“E“—D Ys“S›€UŸQ¦Ÿg°»vxØ£šªa¢œa^Ä’~}ª©9ÍÀ]¾è°ÕϘ…É~§·U¼|®|yf‘š^†³tx¯‚…q^ŸƒlmÃp‰Œpx«ihˆDdtZˆ6šÌ™ÀŠo ™L{p=`"a`&E‰2E;G"EpoefKZ)e³X‚—LV‘U3Sw,M[%‰š)fuc~“N¬nEl’u³”E³¹j’Æ–Îн”Qš‰†‰¢PÁ´nùϓ֕­³`еf¤»WгrÑÆs­c¸®Nv¶k ¹c¢Ÿ^›¨_Ÿ¦tÙ—ŽŸ¡k¥‰=ƒ·NŠI›Ìl¡¸^Ò´aq¤l[}P]l-w®;‘aJvùF…›;’®Zpžc¤o–¾YÑω}Òci™H{“Tp”\¾‹Vo|Sg†b`xrco]Mq;si@ˆºUj¨_~qC€z]zZ-h_8´›`µ­P§ÿª†„Ahª`ª„<~¡Vj~2ÿÑnþÿÆtd`€xp´ÿ• ÜzÇçrŠ™£m¡ÓyÄØ¢‡Ò”Zˆ4wc2‡Óh„­K{¥nn¢X³¹Lµÿ€w–Q|^ÃÄ€·¼Šîÿ‘”¤`‡¨] ¼xtK°‘ˆ~ˆVhŒ9wo@umMžvRyDœ_m_Y3dMln>™‚C”{Vÿÿþ‘ÔŸCZTr9n±ÕfxyEU/zsB’Q˜¹hæ÷Àp‚p¯º™Éê—1D!Á½`îÿ£\Ä(Sh.u…bŠ P¯¯µ›Ìy_˜S”¯~—Íi}·\³‹ÕÖÅV‰!c{Ed€5e…IUj;Fo*:R,¥¨’WwHƒ„•Éÿ–«Ú‡P|3^yJ\tZ‡¯e©Ôž‘Ážk\…—u¦Ø[™ZŽ–”¿Í’ŸpPsGY74H%hxPW3?c3b{a`‰d}œqt™nao`~¡\Sm;IZ7t™C[k@•Y‚±`nŽMmTn}T§Zl¢I~©_‚¢]s¢_z´h³\q|GnNr—[±á€¢Ú_k•Y„™C}’R]rXggtœjXzMXd?k¦Kb‰E`VaskƒŸl}¤^Ec2dpCjzJ}“B[d09I+BQ:v„g^kE`wCz…_]xHg€ak‹glDHk@Gl)F[бao”Sd‚r˜¸a€‘Vm]´u† u€oŽ‹R|”Xf~KqŽ^‡‡W‰•d{Ž[•²g“·e¶j‹£mŽ£^|’X~§_‹­~‡º¹úÓ~’™eŒ_‘¹etF€–K`Šbƒ¦`xWbQh†Qfr—½†³k`i>BYHk†Jr‘h€¨f‹¥dt~GGc[`eg™s|˜‡ Å˜®¿…ƒ«sˆ°rr™a~žer]o™ZK›YIpdWaC_r4UzSaH``E_n=juGs…Dj“OkŒXg‹JjS`}Lpo:~n:€Cj“[w~TŒzBµ•K²Óv›Õ™r½‹€†b‡“CŸ¤OÊjž¼o›´^¯¥cw¸‡hƒp—ƒE¤Mv©opUŠŠMw¯_ZREnDJX4_i7–e<¼c™ç¨–¿²©­~•Éx}®s—“U€ªYh˜ghŒT†rMvƒKƒ„csZ–£\…ºix™mƒŠYrŒEg†W_uN†qD™F¶¥Oª¶[~¥pl{WWOwZK£w¢¢WŸÉq‘À|´®uš¼…Q¯ykmSr~N‚QÀ›Gk–c|b‚˜^grEn€AuˆFw˜OqŒCt _w“5pyk•YO§Ur…6[•Gfm?G†Ç@fÐiœdFCˆaWb&ci7gC{GžR¥“M…Æjt~s•xI†Œuaf€˜ip­ÈRÉÝt†¾›w}gµ~P“ i¦k« N˜ÈŠœÏ‚— ‰še«Ù^¡Äd|®zsˆCZeF‚t5˜‚M˜ªl¹šwÙË„§{z€ìtÂU¯ÝÅØÃž†Äêêb{ŠKެMY•Q…~?©¸NhÛqƒ•@¢ºY¡ÞšÏH‡ÆIdžSeƒGô±I‚«SZ“Fšš4ƒÎ`^‡b¬Œ4…Ý{‰¬r‹xF†vr¼·†Ä‰„¨»\×±yÙÿƒ¶Ø«Ìÿéo€ŠyKc„IÞzB—¢§Ž¡S†ÂYlŽU’¥R¡ž]Àîv ÿ†çáv„¤Œ¬ŒOz¹gp¡Qÿx=žy];~T‚½Q‹ž:OnZ†iEŽ˜co›i€•O~€Os§k’qNצ‘ç‚h•LeuM|’SÌšTgo;psH ¨ƒŸdŸ¸]“¹[X†5u„'Xw5|~Be™F]t+o‹O¾ÏzñÿÎf¥Uwk9¡P‰MÑÈSùÒ–·žrr±4ÓÌ–œñ±±ÛšÁ¶^¶ÿzjHŸ¿z‰Ç†‚R‡TISr&uI~Žmuzud™SÚÿ•a‘SPk+V^(t£m|FÇØm¯šdÙí¸—Ï’Xk6¡œoÿÿu^5crD……X†š@{e5·¼qȼšŒ»S‘ŒWßwÇôµÅØ¥†‘Si7Jl7—_kÙÿÁ‹›m¬·o¯¸f¢ÕX ×b|¢Z­ºmu¶Y¬Ãކ³eÀÚ€Öÿ­^€<]…2´^w™G…^h”LyvmŠ–vG‚6C\+Ž‘¯×zu–Vd‹Dz¡NTk4V}9f‚CЍbT€HW”jÁɹ€¢h~›nz¢H¥ÎPfV£¡ujhv‰jn™v»{Y’4S‚7qªXAb0w¨RнH>h$EZ,^mNzxSpEn˜_{§PoŸ:_uDQ‹6CK(Gb]œ¿›´Ï‰Áåze™8]‚?жXXxRcyDMu1a~HPjXpwqž§tŒUwWOc-^tj’©Œ‹¤\“€}fwOTl7Ic0Rr\šgtšMx•_¦q•©ijyDNY76KFTc?KbFr|Osw\de;LT-NcapT“ž\¤rs†Ml‰b}·s|¡Vpb€£h‹¼ŠªËƒ‘^r€e†”SdtZ~KZ}AMlD>g>EW5Ta1Zk3^i.SzALlKSC65C(2B8EJ=Y"h\"—‘4w¬]š Y‡ˆb½}X£\g¡Qhp¸Æbÿ²x“ïóš†A°æ¸ttpÿÈq{¨^ƒd(Ž­bµSiˆO¦…Y­²btžT„¾tî¾UÿÿÿäÿÒïÿ»ªóÇžÁZÖ–Mÿ¿Œ“©VÓ€~é¶¡•ÔWµÇa—шa“6|„7by6bj0‘Ë2s‘Zkd>}ŽSˆÎ‚¼°yhÞXƒxBˆ£`Û–Kh…Gt•V“\p±[Na*~R[ŸLwµƒažWby0N€@‚3§È^Ðæ˜Þš°ØÈâhÆð²xÃIǶŽêë¯ÏÕ¶jsY€–V†ò¡Ê§sèÿЋƞ«o‹¯n²³‰tǃln=€ˆ>‚˜S}GEyPHX@EW1@Z4RH&|b)’Š3n°Xi›}‚Z£fd£ve‹l^}XSeM]kC\o8Wt?bcDyw7šJž¬g‹¡bk‰^V€TbcEmq1uE„›T®e ošœmš¨|®t„ªmˆ‘cjVnˆQp†Kk…QˆƒPŒ aޏ|¨v¨t‚°g}›_v–jwpU‰TR``a`>•l6z–Kl‰qelRpl?p<µ¨_Õ‡v¶•†žbŽ©F‘³b–°r‡²jt«„~žg”¯k•·^™É‚ƒ¿t‡Ÿia„cƒeUž—F…Íu¬§e²Ï}¨Üv˜Àx¶­Ïß‹¡ë“jÉ’„LÈ£Q§¯c˜‰m¡†R¡º„Ä’½§_¥Ö…dд]tG€bA`¡MzFk‚9ZyXvs9w‰Mx„PuEwIw«BixRg`N7h%•ËeZ¡„=}ElW)¯ŸG}Ô—\’hÄ‚\‰ÌÑÿ£G›á«’—pš†A«”OÂj„°reªxxœO²›I¬ß€ÈÃÓ¼‡ØÇpÿwš¬OÁµ]q›yv‘?ioF‹Bw•DZŠVsr)½‡:»Ûšæã‰nÏÅ¢Šx¤À}½ ”ŠÀ›™œRŸ›JϽ‰¤õĉ«nhœ]mtDزfþþ‘ÿé\¥jixD¬ªXÊnp¢aN‘H…w)Ü©Zžú‘ÜÔ‹¼Å‰h¼€ŸCƒ @o˜cx¹Iá§6m¶on€=™›D±´As¿`‘ižsŸ·hâÔxaø¬ –F¨˜`ªä›ð¨x¾š§’g­ÿ œ†b³‘®“¨WÿàuÀÎyu¯kÓÃÏÖ—ïÿ¬ðöחѹ‡­‹‡~<¯yÀÀ–ðák}‘˜’›ÿ¥³_kv[SiÌIªd>v¾zh}^РeµÙŒìå‹êÿqÂÿµtôµ›“A™¸Yà^Tfv;TžVc}Z{Ëa^¼1pDnZ4„yt«Ê®´ŒDw—j˜hÌᢺÿ¬¢è”²R³ù‰´ç¢©”ZŒÏ^x£Uyƒ“T©ºuÇm“¬wBZ<{N%‰I¯Yž™€¡Ð‘y¦N‚…_”4€ÈY§Á^¶« Ó v«Ñ´Ž‰”‹WnŽPŒœTÌ’€ÿ²¬Ò®—Ëêp£Ø[⺶¤­M·ÎZ̦´Ó°¶·Å–±t­m…jzf`• sÝКðÿ¼ˆÓnHi(A`Lk2\s1ãàµäŠṎÈÎËÿ’ÃÀ‹‹›M›ÁK§µ‡†¹j¤Ï“‹Ä¡ÇçÍ´Ì£Op”Dg†AX‰C†Ž|iŸH‰n¬Þƒ§Ó˜™¾ŠJ€>ltf^s?ÑÜa©;v˜[Žªl•»`[ªk‚Ot¦P åvœÆ\†³jФR¿âˆx¸YwšRy°dj™OfuYÄwœÔ†„½PyœevCn~Jv€N€Sd’WZdWhQ\hDfl;jn9ry>hQgƒUj}Il?c…M^uKf~H†‚E§RyÁ‡z›~‚¤khª}T‰z^mTXl:[pBXr<]h>lu@}E}M€š_j’_q‚ZsŒP|UŒ‹L…œP‡§]n¬ay‰`†‚I‡‡Xn…]|ze”pQ£l|p{™Uc“[Z„_hsHŒvD £[iÅ{SŽhMtCIv2P_0fe2{a?[Š>^kDŠ\8lŒF„’Q”©O§¤[Áº`—ÖsZ³†ƒyV‰8j¬np‰OfDXQwxMŒœQ–ª^‹Â”ª~p¤iiŠV…“Hv¥Pwždk¥h˜“_˜Æ|‚®t¹u­ì~šÝ®`¬™…bPªw?‰Œjvf„N³¯s®Í–·Å}¨Ú¦aË¿ƒxlaœ_SpXŠf6p§Kne˜Jo›TP€iud<Š‘Ir´bjMzg)wƒBx‘BZšb^rJŒwF}¾n³¦kŸç~LªoHi2gf$eŽ5OyNcl3Zv;ao8NntCePjMB~?‰uAh~V‹@}²s[’Tjf,b€2Ql4jq)£ƒ;SÈJmdwy¢HZ tSyjGYʺ_ÅÿÊ•ÿ¶t©hŠ’S˜ n¨–c„»”·—V™¡}}CƒzPrœJwšVz€b‰¢y£}w‡±m§Kv Rp•QXŽ7ho'¿…Kޝ‡›®`Ôênu±s¨œE“ææ—?•Æ©ÌOÂ~Áÿ^ÿîZÿþ£¥ÿÄðŽ_¯ù°¯¹yÙÿ»=ˆŒE_'³p2q¦i²”K’©¼½i•ñžs‹hfd:š`<ÿ瓹DŽt“d’—NใÉðµ¿â³‡Ç¬Ñx–툾Ó{¿Û}¤½|œ¨u›¥Å¢[§KŒ§VŽöŸ°MrŸ`ž¨XȤšÿÿßÿÿÍÝÿÐÿÿ–©ÿËy{Je}8œt7™ÉiPŽQaz.d7}¦hnºqz„Ct³Gn”Sh~:³Ãvõá„Ýÿ˜{‰”¹x¦µ_β…®ÿ»y¤LœžaÒÁ‡Ýÿ¡|µTˆºm–­s¸¯žµÚ¶‡°B™°Z à££œu¢Õ…•§QmZ2wo2`o-ÊȧŸuH Á™^_$„…G¢Âyœ_WãЭÕí¹Ž|Z…i¢©¨r‰q›–ruÅeè–«ÿx¹‰„oÇG\ƒ7tbI˳”ŠÍL·^¹—”ÿÿÓhÂQœ\|­VN˜'ai4ÁÚ¡Ãð•ÆÓtêî×i}ufRzBu‡VxY‚ÛrZ„RHP)aYBœ»‘›Îƒ„nU¥§…»Nc™>]„:‘¬j™¿“–µ‰Kf@\lX¢|™Áu{˜QszVdŸ.z–^¬ÐàÿØöÿàíÿ´¢æqgu^YWuœs—Á“ÖcŽÈ[y c†¼ZY|A\f=]3]‚_µ¶w¢½q“µx•ÊrÇu»^Z…Sv˜r£«z“¼ŠšÐ„ŠÅ­nGa‡FhŽQx•Z¥_q†R„‡SsŠSy‘a}¤ˆ¬ËÊ÷÷‚¢LavIYlešv|£hf™enQl‡PyŒWkƒ`ˆ\u‘E]~Yr–P]€n“»œ°Æ‚…’DKe8?f[t‹xޏ™±ËƒŽ©s¤Z_vXy8AdA]}:RoH[k;[qA_„GI|P5cFBL3IQ+WZ4[g:bc4m{DuSz‘Tr–\o’`ccoŠ\ŒY’X†´vµ”z®„_˜nas^[†MYrJ[l>dtBuƒAj“Av}K[|FapKRoAhuB—{C‡¡Vk‹e\„SksPg~TyxOtz@toHttK†WŒCb¢ioozFS¤\D[Hm6Uc"hh)QŠYJr_Cn1Wc!Ba$PZ+Rb*B]6f[=¯k,‹ÅL¨´lºÇl‡ÚŽŸ¢…„ªaf”y]zTds-Z€O„{ISš:JiDan4|}<‚”O…œjrd|—c°˜U‘Ãeƒ¿~€œ^o£f~YŸd{Ÿ]²ŒR’Õs|¾‘i–gutD„‚6|P”“X–¥e³²x׎±³t¥Ð­ˆÑ®^­gms[[“[‰x9ŽŸO†¼nª]‘´tp–eY<‰c;ˆ Rb™iŒm2~½qR£i‘^=o·Rœ¢hf§`›ˆl™µtLăq_:{•0‰¦_q¹m_¡TWh”I±›Rj“H|†B±n¦is®Xal=‹bJ]_–¨NòçªÆ¿s‘ÿ¼‘¥F´ÄR–HÌ}‰·ÿ³hœYl‹XiQ‘wO Ãe¯ÚxÀ¡‚z}sxaJ¡ÆI…³TT}:‰kq’¦eªÂ®V]/IS’WPºÙ”PP0†‚/ˆ»WÃê‰Ùÿ©œè{o]CËЂ™’f—‡DhHp`.¦€Y¿²šùÿúÿÿÿñÿÄÞÍ¢÷Û€‡ŒIw²RÑæ²vo7æÆÿÿ䛾väÿ{Åÿ»b’GŒ¶Xã꼼⽨‚}üÿªÃØgcŠ8{šasÉGlƒJÈܳ½Ý™ ¹‡a˜D¢s[ŒjŠKw \n‡gj‘IQxK Æ{²À‚Ãý†|ÝT¤·W^†Q—¥ —œ’¼Å ¸Õ¡¿Ásˆ¿[Œ¼tb€]tzsfr\QA`=Ab+BX$5Q#QkBmS–iŽ·{|¤y…Œf|œd`‰bx‡M€™F7N Sg1q¶PÑÿªšÛY{½iƒ¹¨žÃ²¯UKd6Hf7B^“˜Vѱˆ´¦Y×óœØÿ†Ÿ–dÃØ™ÜÿßùÒô¥ÿz MOk-bŒ6Ž®~ƒ«i­ätÓ€ÁÖ©×é¹ëêÙÏÿÕÂë±z˜j[oWÑQk×=E`<†ybËñ«àà¦ÿÿïÿÿÛÑÿž„½m–PUt9]dOUW6WSBuv\g…Agv0_|1™’a‚˜Ou“e¨hkœLL‚;RtLšŒ¡»É|{‰I^oC‹»U¦sFY8nF~›Wšp¡¶‘‚ÔM9M0,B+]NH_GN€Mf†R=j$v“\e8Am>`lOZ‰7d–iº…·Ú«°Ó”µa|dp“h\†Cj“PTv9Ol5~£ObiC¢…a®or—f…”ˆÉ´ªê·“ÁÉ‚“Úk~ÅUi”;dzEMp99T.Ce6^wUm…C]{>]xv„•‚r‡p¨`\}GXtHx‚O^mq‹ŸUmMEd;\Žf~¥oz¦[To?ewIf†cË€zž_ftDeDl~SuhŠ¥cv¤k‘±wŒ¢]oŽv„žo‘½Yb~R[{qkƒ]\pJ~‹R^oIw€CWq:n†Q‚‹k®¿s{œaÂ{–¨Ï¡¶À›®³ln„Z{ŒKn‹EQuLGgUTsO`…WhŠZzœ^p–F^t5Io@V{V‚«¡Æà´ÅìµÏÝ`e†@UlBI][dbm‰mƒžT\u6Bc>b„4=`#>T(I`/DnESŠau¤pŠ¡f}~Ie}@Om3_c3Zj4im6\7m~KhƒH[tMOwBLU8LV1lU*nv5HŒPE_QV^2bg/Zy>rwUq“U€‘c“Q€Ÿt†šv~™gyšXw›htˆii†JY‰Gd~Mm>vwlnLg†AqzQkŽUvzWzuEwnDmtFnkQakDUm8]u2nt:_u=QrIH`CAl;>fA7]?=L2[R$†Pƒ;X±_?†Z6e8MQ&h\ lJp‡T‰rYœ˜T‚¢j”’d•±f‚¶‚ƒ¡y„Šic„@szBn}=c‚O‰uDiŽIf•PN†Evi‘©a¦n…ƒ\h›_‰G–¨Xx©li™Z`wHmh>§§?»ÅhޝŠm¦{S«›HÊÂy…Ï™€¤‹;§vkKQjQ™GʱR‡£[Ñ‹JxÅT‹D€l‚˜xu§UtƒZ‘›X€±_VuM}ƒI€ŒCƒŒŽ¶mlµun€QR—`Kw>Bx(Q]!f~(^{?o›C›‘Uz»Š®gx‚a´W¬Ï‚æ|¦f‘°e~Äx†¸^kºsce^€7„‘7[¥S•ŒL•·†È¢‡‚ðŠx¡[Š›M×´€÷êߤÿÒwÀ~¢¶IpÀz¤V•¥{j–p‹Fµ‘_­ÿs‰Ýx]žnZ1ÁnU·ÚyšWžªgj­bR1‡-^ˆX“r(”©p’œOX£Âcs¤Jþ‘T’›s€¤N†žWk‚Hi°6[|8Žh4¼”L[}H{…\î¢Lp´rw–@‚^›æˆ¨±‡fÙ’Šr,c¥nh·Fs•2n¶B—±‚®bƒ[›¼o¶ä’ÿÿÿÿÿÿªÓo¡°g¥c|”@[c1]9—±RcWG™šNS`=\8b†H——’ȯ¸øÿ£‰è>?€%&<25./65n‚Hk—Kn{@’—7ÿúOAi)7<Uw4Sx7Qr/XyGWzFL[O|¶j„µm“¸ˆ±‹’žw“ª‹‰Æm_‰8U‚.Y„.Mz2j’AlŽNt;Ku6U|@b•Hp¦WXrDSiB]wgTbI^m`†©Kklš·|~›Zw†t…–UeŒ[^|Gh‚_ImO‹¯y¢Á_‹…d‰¡vyªflJ^p7`s>XrW~¸wŠÌzg•Q_lKs…Np’b}“u™ÂqˆÂi…Èlu—Lo‘l™©_{ˆTf;Zi>i„TtŠnŒ©žÌ¥è…¨Å”œÀ„‹Ÿ‰œ¶ˆŒ£y|¢`y–en†9Ta5MoDVzLbQX„Qm‹L^}AWˆESpb€‘p|‹–¤¾ ˜¸ew›P`F]zX~«]‹m›´`}›V~‹N„’HnŒCdwAP~Xužbœl€‰dZzKEjQbˆ]\`/df-`y>\tE`s;gyKg„GYTFuSLd=UM1]N)`e2LmDMbLP\1`d-hl6qDh—GX‡q[kYXgUjjQ}Kq’\oŽly|`yHf]fzSpnB~{@f}Hi~Kb}IvwOn…AnŒ^nƒQwuj<“g)¸nz´X§iTzMii/d…>bQ€iImŸGf„X€`Q©‡Oš¶`ž„‹^eŒMv…Zr‘9i‹b u:«U†§fxœb…”S‰Mq–gU„C]i8–o5¦¦G|ÆQ„_vMW‚FŠ~?•»Sp·djŠfp‡b‰kƒ­n¢‚~œX™¯T]¹nO}cXm:>‚KFT1\_(tw;‚Mv“ou„YZ”Kj}Eez9²}KtÌZ–¥U™µO^¯v\s^w`.eb:Íz3ôp²¸Š©ey¾|Ž•t‰£eZ‚sgpELcKk_VVŒoYv-|FŸ”Za†W˜d8y™…‘—a˜„v¯±pc©wiUZ“>d|Ay{Gc“;V,jd#fK vIn׉_vª[’ÇM Ïtrµ€q®Y`~j¢—P …¼mi§lpŽMv <“Ÿd{«hq§VœuPŸ©u ÕrŒ¬f‰³rªZ”Çz€°–~¯es¯ey’Yƒ‘fy—U ¸SŸ¼|‡Ê|~“i|¿_ ª@ÝËTÐØ§¤ÿ‰¥ÔnÅÇ{L¾„?r-Dg,c[,c“E\€Dqi3‡‰Fw¯ylžQs}<£6Éâj‰ÿµ’˜8u¯\yJ=a6I¤f–f'¸´eÅœ†ÆˆF¡—FˆX¢aV´“†o4ƒŒx[›j¢ƒTˆÓ“³°xèØ¿§ÿ´”šUÒòœ¾Õ©ÿÆ£zÐÒ¦hÙÿÿÝk|BŽÄC¡ƒ=ošo™ÂtÊÞ^Ó}|}i“Bw­Hr’h¬´K§Õ‡Fu@¤’5‚؃½I„Êb^šCmx.p f¯3Ã÷騽~ÅÿÏt†=iw9¡™TfŠK|‹EPm@fŠCtŽ;¯VqyOëÆŸ÷ÿš¹˜h‡Bt“Jh‰:KyBQY0ZY?7Q$QI(dRNJ|/mj?y{W•ŸmÀ䎚ŒT˜¢^š’A˜ŒY÷ÿíãÿÝáÿî­XzÝuTv:vqZs4š¿|Œ²p`Œfxc7fZ>‹¯H’Ü]hœ8hšFbL‰€PÿýÆÀÿŸäÿÈ”×qãæ­¥êw~§L=?'Žhf„Y]‡kReXJuHO„¨Ns’\x¤Vzª]‘oäñÓ¯ëªÓÿ³ºÿ¿z©nªÕzy”dªƒ¡ÊðÀÐô¼­Û‰ÒДŒ´OŠŠdˆ¬xa|I†·^ŒfHl.FCA³š}ÓàÓ¦ •“®ƒÀôž‘¯b§íl‘[žxQœ™^ª°z«»ro€ZÒß¡Zj< cŒ£gPPR`[x°¼šîîÞ’±UU_8ÝM”ÐY±ÿyšÒj¢Ç{ÑÞŠëämƒWYˆ(Qw+Kw@[wM~Ÿ^CX-}šT¼¦ZƒÖkyŸmf”fh‡Nx˜Q§›T‰¥x‰¨~lœYM‡tlpBlˆCR‹IfaAfi1tn0ƒ”Tb¯\i:V†INpFgi2hp.°ŽL†Æaz¨q–”`”¡j¥•S¼™N‡¸_–l‰½{‰ÀWºqqiT_nFŽo3‡ÓOu³R}”Lp£\ƒ­_c¬c‘J¡¤Jg¯WtiC³€M{†h„‰jbU‚…O]­H•v4[µgV–Gmw0ƒO‡”dŸ©c‹¦{Pu2i<5EhJk–8c£N|ŠLcœYm?T‚E~z4x§T|sf•`‡º„T£|fo?dHypZbšfxK`°PxpP‘šSxŽjŒ‡f‡‚Xʺb¢ÿŸ €ˆË^›½`ËÞ‰yÛ¥fœ]x’aP”euG¬³q†÷pk½uyµA“¬YrºkyƒPeiQ×vUrãŸ_€UCiJ?p&HZ“e(Z­fSu3\r1Ui8±mAf[b†Bk‘-˜O¯Ôˆ¡a“‘N‡•I”wCj³m—„=¡·kЦM’ÿljØuI“[‡@•§Wg•R½“L¶±{¡¾ ¡Žc°œj“²U°†yiZE’wBJÿîzÿúŸîn’–Y„ŽžŠF¸Àm¶Ê{ µ•‡u·Æ‚æó°íÿ»îÿ¥;À$vE4v=‚Sd~4Yž)\j6”¡VÁÕš´ÿ’x£EŽ›wüÿÿÆçËØÿ¸ŒÄxŽ¡V±;Pm0•»e°ÔwÄzk­¯’¼å|Ùø¥­Û~¤¾™y¤bq|QYƒ7b†:yZB]!TO<²g³ÓžošK›Ž“Œ°U„œS¿¾{yŒ\—’qoœWŠxjˆW»¥mSh9+-*7 PN6[lA^|8°Ò‘·àŽ¥ÆƒËÇÀ×ò´¤Ê}² wƒ™Dy¶Kd¼:z~CqwHav5€šak‹K”²IŽŸOJm-&7%35J1{©…‰¬Žƒ©Š¯ê ¸ë„ŸÝ|‚¸Hp›Q™Ådi›mw›~¸à´ÁàšvYa^b|g¨Šm˜¥i¢æ^…ªGFbCPZFi‹ERgIYsIQr=iŽW~µUsªkŒÀvr¡SXuC^†H\€T‹¸lŽÍj{ºN‚»hŽÊ^jL]y`Ч†~VPs9UzCi›Po¨cаakŽN™¾vs•iˆ¨~•ªZt‡?^u=Ru7Zla…ªryi†´p‘Ãu~¨\jŒ]…n™œXq[}š^V_Ks›–ãÿùÿÿ²È鈖¾]j„Wb€cyjq’ak‹^yv›¿¤¹…’¢St„BLi5Qn=MqHgˆYlŽS_Kg}Zm†HJf*.N:Ff_†¢OdwNj˜\q¢Qe‰G_~>Z|a`…de’nq•\sŠIYlN_mBIk9QqDU^,o]2at8U~LY{Rem9cp@W|GXeLif7mk:Sx;^pNr`;gxEfcCRc9?`6pN6Sy+HbH_H-r](wa8_g=L`EWTEi\/fv7_€G^b?za@„r=o‡ZcƒkHsZUYHoM0ut;ƒD^›OXr[W_A]bDkgAPvGPfD[X2^X0N`?_V@R{?=cSM_A_a'hu1q‚7Š•9}£Va^R…`hd<’o4˜±[e¨wQjK~VA€b)†8vŸV|ŽcŽw?{¢S®qi©^lŠj™ŠFµµSš¿€]­ŠOzXrq=‰Œ7|œSr|R„NŽ•Oa½nXv_„jbaCwxCvž_Z~V_j;{O7QyZUZ0Š‚*až^RnRqq<]˜Fr~6ª¢H’õl•¤{­Ða«å…Æ|Œºst˜†¸[z›c^Œ]’3®³oÀù¥¿â™xË›ª±MuäpsšGt¡9|Œ?££Me±X[†8h‚-\{5^€8€˜:P¨J–/o T‡žJuŒIvšCGu›Jz®[loHuvEs„PvMƒ›U€9ŠS‘zcüă©h{ˆJxkCŠ{Cb¢u›¥P€ˆHŠÎl­„=ˆ¦‹~‰Nox?[€Q_>KSCYX4ca3kl6Q‹HWi?kj:[i:XS9Ul?5mF=O6cH"eZ'ƒm6g VZdYhBXrDonCqxCa€LkzDms9`iBiDrŸKYwVN[;[d-um4‡5s¡Xw‡]j_BcpRMœ†@š¾bm²UiWZh4j&”J‹¾u[½‚ircŽ~Dj©aoŒkiCЇCu£P™okšph{V«x?…Gy™k_]\{@~v@p£Mf‹T„y?fKspUe†L‹ˆN_¢[KtQS\:lj5st>f‡F_FTx:mx9`Y2o4‹ž]`ŒaPd?qb2R’9FnMlW)Žv3‰¤P¡£h]’Y o>¸tŒ¥mLp]YBq~+KžGol/ož=u–i‚©QEwbV\&zg- ­]ÒŒŒÆ„›®yV»ŠuQkd€L€}?w~E•vWyVPxM³V+u¬VrŽcU›V~}3g‰Y{‘Gk›gIyYGf(Wj28~4)8,W5bk/jyA?\DMW(UL.bj.‚‰7Q”oli*M—Sbw&c‚DPxH_R2exCby9|~9VuKe€=FwPU9/žz1£ª‚®Ñ~hœ‰†‘]„š~—‚ÿº€´á‡{¢Š`”U—¡M»wˆ¬uœžOœ¸xeºw`tYxH^˜N{}@€®]wÍM޹VwŸaœ­kl•_BÉWDB&sX3wÏS\›^ i(’ŠP¦D’N†gP†˜@Z›CkŒ=q¦FcŠ;Sj;œ‡:u]“€Co›Yf‰S·’Xu¾¢Š_D½’T©§ldQ…z<[†OŠ—> §n©®kœí•¨ˆ?Ðu«ÚÿyOÑÊá‰ÁކŒG©œJ³©‹¶Ä„›‹J˜žT›ñ•’[”ežxWu—X¤šC„ÍzP™J>Y-BL+:G-:M/c]JkuT¸§dpÄp_ˆH9J&‘ÃZt°PkrD¦`žÚŠçãÆÌàÀ¦ÜpëÒi¥Å^Ž®|Äqº×ƒ—ÉoÌb€¸yx´u~²ox§zwÊfhgl…e‘¢s€¡«ˆ£}©¼’•~ËÿÉÿ˜Åÿ†j¨1A[&:J,PZ;`}DVf=X^6e†Nn°^Ÿ³}§é„Ìdˆ´‰ŸªŠ‹·mrQ{‘w‹­b^`v¤sƒ˜|¸šÂ‰€Kh“J©mšÉ‰•Yl‰I]xUyhœÂ|œ¾ƒ«ðލéjVw;_{Q[mIWi3A[7Tm;RoTx–Zl‚iq–\a‰^j”l r‹µm„¯`p–kˆ¯eŠ´‚™À•œ¹{Œ¢Kf„In“\dNf_¥¶|Š™W›_~’[c|Uc|Q\rYq“u’¥e€‘Os‡BYF_~?SjDVmSd‹fœa…¥xަ~”·iwŸVjŽRl™[u‘e©™VekJYkEZgGWqebuhrai†L_jL[yLdxMx¢Tq•TBZ7OY4M_*Qa6e^?vd:{uC^^TtoSbHRb8@e3/\5:C+HGPV$WZ1Cm3UX@Ff1YW6cR)Pb/TREad7clFquCUp=f^F]‰@bg;[t;4gB:<3EF)GU0Fc;eT+c\*€f{“Q_S^wKm~9V…G-¥™lQe?Ÿ…ŠŠË`f¤2]r,„ž?N2{VQCd%1)69'ZL3DP-g=ir^äǺ·Ú²ºö·†Šnx«Q—ŒZig9‰P?e(pec™½‹’­yÆv|œRp¦?¯¸ŒÿÿÒêÿÕÄÿ‹õÝ–«¸¹é}®±se„B‰{e¤h£ ¨µ›¯ª„ÖÙ¶ÙYŒ–L™mÄÿd¦1RiJ¡·s¯Ö|©Øˆ…§U³Ïu·ú‘•Øi…·jmo¡Þ‡ŸÛ‚Òy„ÆlX‚VŠºšÎñ¨z²PWy2Fj:mf~XktSLZ8Z~L„ƒyˆ˜t¤kµ^~©StB~‹@\k=dz;[‰Fk“n’”{¬ÓŸ×‚|¤ll~YYb\s‰{¥XlŠcˆ¡l…¨eoŽb€’]‘¡w‡Ÿ_`„KhŽ[}«|—ºi[jEVxKNsLk–keŒ]m’o‘¬~|§JMn:k‹Rg‡M[„d|kÒ½ƒ™{‰½|ެb Zv‰JWx\†Ÿcs‚Uv˜VnŽCeŒPo~=YsER15^j,omJntI]tKfjJjo;nbDke:RgAOcCK`.d]2]|6]m@T\5€`7w–=kh¢rT–L…¤{˜_ŒT}}Ur|JexXbqDj}I|yDŒu>I€nEs}AvkJ_zGfd9sq>~vEr‹Vf‰gysOqlKl‚Je‚Y`~VkxQYeMwTOb6b&xžDFªmIH7OV-Wa4mgJ’{LPvMjlN~‚.¤T‡ž^m¦X’V|P|‘Ze“Mi|@d|IptHm~MzvC|g@ol5gxR~zEp:rWuo9†x9_}HxwAbŒCl|NxvFmŠBŠsLo“=v“OgqInd>h;emNQmEib<”ˆ=\¬Us‚Kš@ЍJ„¯f‘¤d­Ëa±ës{Ønšsj¨¿|“¨£µ†„™``˜[™‡?|»q¯}{Á¡`ˆ›b—°gn°p¤pCžÏhw·{x—]Y]Kz8Yu;N}??Z2KC/mhBXgEMsCFQ-md;cŒX\zABY0P`(og>©B|£ˆg—QU{B[{2^s0T|?Bs:b]$tr5cv3U{7vŠ;]wK’sF›ebKXŠp•„8|S{ƒWL‹Vmg*u–APiGMc0…c&Wm_jf*ç7ŽÀojkH†{9‡v7s£EMpdj:Yg9=J%[_=‰Œe¶Å†ˆàs°Â¤7O:Wdn1ŒƒQÉݪ‘ìhÿД¹à|}ˆP_¥e¡vGÿÿÿàÿ˰Í^Š´U£|C£‡Ey±Tƒ~CȰd´²\²Ãj¿§¦êÑ•˜gf£nÇ霶p½ëyÒü¤œÇn¬æqÅÈ”Òÿ¹Œ›vÆÛ³ÐùҶݨ—ÀVTu-ŒÃOçÿ¤}ÙRÁ¥_xƒQ}’c…“qq^§ÇjtL£¡Œ]Ž?Sd0gy2ÍÈsOl9ŠŸ“®ã®„¹wqŽPP„1ªžŒÁß—Êç¸ó½¤ãÿ›±Ò^¨œ¥kšI“n=§‹XÓÿš©º„ƒ¢P…]ËʰÛõ€’µFˆ¬c¶Ö“Sb+WP-qq^”‹W‡¥_¦·j‘¼y­àž¾ï¨ªÕu–Èqˆ°v‰ ƒ‘´€˜Ãˆ‹Ì{y¶l¢Ö™V9@ZJl6l‘POu7U†?m‹@bC‘¢]b„RjœXp§j{¬Š­flu=or-5A0xzZ²Tx¤\|·_y­hsžXl™9S|U«¥•«qp“Nc‡_ƒ¡TUIu˜cºv|«_s”W†½`aŽep™@U|AUrRl‚PYtK_€]„›gZ{S^|=X€Wyªtq«bp›Hat,Bl.Nm?i„Qj‡Hh†;Nz9Ig3k€n‘¾€‘¸`ˆ¼y´qv¤HEtNZv[qyG^†Oy¦o|WÉq«¾gzšz‹­{„—t‚šmz‹Wz•gftBawOn‘Xi€QaŠPcq>VfCm|MZ€kr˜py–e|“bu‘qy‹y–pph7YxPdm?b€W†{,<[/B\6>P?ZhDVsSay_s„Ui~D[mE[sILpE\UO_kv5ƒt6xˆAœnJ•n>ŒiKf†LoIyw9|qMqr@dTˆ|Gn~Jp{Ca†b`}WMzOJeEIW/UX2xU(Œ‘;H¹xTbcuW)dj6^c9cz1\nAbz<˜6‘¾jˆ©yxŒ`u‚_f‡BypTNˆEh_U†G‡t<‰‰NncWwmMeŒfßy8ÿÚŒg²™W~DiiR|}B_‘fNtPj,Z’4Œ‡;Q©eUm-Sf>\X)“­Hu©{µIJ¤\bI@7£®{d¸r{ˆ@{ÌLT¥OfwC´JvÁhŽ‚Sjz@j~Gt“BX¥Vb]DgŠ={rB†Cy_eG6^a9o5QrKWqH”ƒOWeeWt1Pf*MW-st(ƒwKay8š? _dSnx;—¢Gu‡QTƒ>^r(p”.ia|–J@nQFj1‚'æ°lŒÙ…e¦n‹zOj‹b•Âaº¬ƒÿá¤ÿÿøäÿãÊæ»zÿ©^HO€<}{>­ÍY’Š]¿³•‡Å‘`«ddp@i‚_€‡@HUŽp(rwcv²E»ˆL£´l¡–~ƒYl®}ä«udd~I`‘jlK,Ÿ“FÙÿ¥·ü”„ÑhƒˆUr}H~²Li}<[l(~£A¶c•¥gq–xs’dl’^1M"FK%D,7I"6;k]%Vm9Ld'Šƒky“G_d6€wsŸŸ{µÄ—}e6`]%_‘‡TF)]W2kl7†ÅhŸÌ™r—[e~`Ïxl¡vuiTuoDnxJcuTb\6hvas‰ol•8˜~Fa~1”¨}ˆ V‰¹ngŸ`¡Ÿw”¹³V{Am¥iŠXvxLo)†…I`M¡{W‘Tˆu]o_2Óì¾¾ÿ§ ëwnOM\;mp6òwt\s(_\/whB‰pHwOÁ‰b ”bŠH‚ŸZßÿ¼Ñÿ¦†²g¯½†™­‚Ø¡†L4zstl{IÂɸôÿÉÐÿÕÿ”žòoÿÿÕÖÿÆÈÿ¦ðh¸g~¡Zx¤\Lp=~fAD/JJ2_qEYo1o|Kìÿ ‚µHwn½Ý¤£Érrš_Re7sy]‡r›Âl{ÃL•½_£”†ÇÿŒ£ÒW—J¦Í’¿±|ñ”¹Î»˜¸òj¢×‹¾ÙŽžµW YzZ@d[2ym5€dY‘£Hˆ;yBdxR¥›‹¯õ„ŸÙ}˜Ävxa =4N:¬…‹®oƒÍr„ºp[‰6U‹*Jj6z­pŠÉrÁÓÿÿ·mWXpK€Ÿmyªkºuy«qu˜nlœCRS#?K6‚w\¯ex“kyš[pKOuTPaN[k‘¬‰u£~ˆ´{t…ZiŠKjžfwŸmb~Qc~cggr„^iVg{E‚¢IWs9No\t>Ug2CW7MeJV|PUwESfFZwIZmQMsGXYAWd2YrC_mAW{?Kh=Pg?TpNvoD|’DxœQz›Yl“^J™^J^JFV5XK2Je4Q^DP_A\e8h@V’HFt^?IDH<*TH)XV5N^>OW:XR3[h@`bEqi9oƒLssQcnRyfG„c:}Jn†ba‚]{o@œzGª‹Y©¨iz£wn‘qd‘fUxTNvF^j2e},]wB}lCm:dI`vKmkL¡|>ˆ°Ux§lfœmiŒ[k€;}b@‡I~‹]TŽbEzYEU5KG#ƒJ%”3j£ii’ucHQ…HXi0ow={H•“@~¬X^”ihl_L|AMmCba+k|?Q~P]Q+kn‹€>tŸSŽŽ[€‰E~Y‰sF—‘Q¶ X¨Qt¤Rm‚Lct=g†=ZwGnc7Ò|9•ÄcÀ£a†¹iy…ds|6mmRn:…­XšY…¹dt³]…œ\wL¹„G~´\{§oZ¤z`ƒWNxKHa>HS$p}7‡ŒYƒ¨OQ¡‹”nB_¹b•xPx·ƒqŠNy‘My˜ZƒO«„G¸p[žlOq7|t)w‚6‡¦Eo—QloNk†Us£=f“Wr„Bo‹EyqQÒ¬L¡Ø³Ÿ¥rWØnJcca\2i€Eh}_›ƒG©œw ®Ÿ“¾‘mªqA~dZa1gm5ttOo—B‚žRÐ|]uäYnRUg5ng9X[6my?€zE† K]’YPXRtb9ĤOàÿn_¹i‚v0’ÿ^q´U„nK¥jC„ƒScºIb4tXv¢B_}Bai1—|>Ò|­^sÂ[dSáB±ÿß´ÿ‹ït¬Ìp°ñ¦}Í{œ²oÿðÿÿ×ÑÿÝrÿÎ~„Ut‘V¬²Uwˆ…azHŸœ[x¼teZI[l(Uo>Xn9Zx+_y6q”@mŠJk‘Ln˜H[ˆV¢Ž2}˜‡o7e‹Hqr9`רkk+]™]ll=t‡B½‚OËߤíÿ­¹õ§¼ôŽ’Ùf`’WK_2T_(rr5^ƒ9rh/Po7X[)l€BgY5>š8?*C;",Fg^1F•`fs=Mm+Ž€=CBRf!rw<’°ib^:¤ªy|yLXf/Sf,nŒD€O@ˆŒh²„zÆ­X¥¸l|¶Qv«;©Ib›=_m(n”ZrvV^i9_†-y~H‘Ãa¥xGyŸW‹‘dÄ‘s£lfŒQVb.grH2m&!?'4'FW!ž|@‹i2§ŠTÇÎŒµêŽ žm}Q{H/^^S(vuP¾U@x•=~qLvOAƒWGwVŽœi®‘i‰—Jçÿàç÷Ì¢škZJO]v8Sw4Jcx±`kŽO{˜bÑÂÀÿÿÕÿÿûúÿÉÿÿð³þ®çŒŸÉ–„Át¸á³ms]T};9O'^O.l|EnŒH;PDg*~ƒ~“Ày±Û—ØøÖÄߤ‘S<_ >F$Fn$DCG}gWsŒCw—5‹˜c¼Ý£˜èl¾Ui“7yS¢¨e¥íƒ¬°hPa2eQ7§œa‚ŽP˜{h¸~Zĉ[wd;me2tu=´Z‹®i¨ÏuepZx‚kŸ_aŠIJyCy¤cu¦`›¸zŠR|™ns®Lv°s¶öŒ³ëŠªÏˆ† dg”;zƒ@_wfp†^]rVwˆ_†s~›PLs$Me6^qRn—Nbs[b†QYv9Ql@Gk8b‰`w¯Vu¦k‡š_WtY®×Wlª[`{BOe-F`CTg:Jq=X…P^‹Lb•NgšHs—K\zY~Ÿvs’bQj.6R'?^Kqwb‹£‡Ãey—PVƒ0Mu9WpHckW}ixœJY}=h•g„²j޵qޏ}†½jqž[m•MYnBYuTj˜iz³lqžbвt´Na}Ji‘Ul•d•§d^qGauN_„CUr@ZzB`†Rt‹P_‹Sj‰Ow{BOeUp z‰²py˜Sd†DXeQs…Jk‹Ub€^‚Lf‹ÕºWw’Fe}C_w;ZhFi„UwŒKcsBMpPbƒCUkX]zG]uH_vBOƒSfkH\z@^nFexD`Tg{Rf†Gd‚\iŒUh€TN’]ShX\U9vk3x‘InªhqŽ]eŽTt|W^ŽWPtgPX?]O0\Z7gS6Yu>IbGLK1OR4RQ:yN/s†HsnPjpSQ]@YP8h[2hiB`mLY_AxO;¬L;Ì}N²—b„kª‹eo£eR‘nlr:a*[~D}i5wk7iJksJ¶nDÿˆ>ÿü{ÿÿèËÿÛ•ò¶z½vƒ|\’N†§isw\…bFtBY\7we&}„D¥hŠÊn}¶hl¦a¡pNx”KO‡djWFf}OUkM[pHwy;jJŒ†Ln¡G`Œ^ac1|w.g‚L„}X¡˜`ˆ•_¡z[‰¤V²§n¡Æu˜¨c…©jg¦oxLj”K[…TZm>io5•u8¬±_t¥p~„Kl‰D£r<²Œ@¬±Z›£d”·f¦Ð}h§s£K¿R¨ÊŽ¨ÑœŸÝ¦k¿”Uƒ|Oj>j.nÇ[g•]¸‡T¨ãœàÚ‹žÿªËÊy¦ç…Œ³ƒ}±gi»Z{ºX••M ±`„¼fh„c³Š5”§R|“gO“bak,|€9áš?­ír«o’‹E¾Â]Ýötáö«¥ë¢Ò„‰·SX¤X^w@pl6]7x…;{‘Oaœo…xEc›\|{IU‚E`v4iuCW”P¼tCpŸwšAdDXs:et;¬m@t¹zŠ—^{–Y‚l:ÀÌN·ÙŽ›Ò¤xuƒÿ„K•îâ|S‹xPr†aŽUØÿ‚z’ƒ€xBv§d[Œh|}8¢±Tf½y›±R¶‡pX´•]Óਫÿ·Æ¾nƒõÈ{ icŒ`r†?ú·/åÿËÿ“Âl‡ëgi“> ˜Jiô¤uy1Z¾lm¿Y‹¯tiƒP]—B`˜D}¨O³›Løm”­‡nŽ•a—ŽW^§pnh+w´e’H•Ož³{¸h޳\•–` ŒO’À`±¨[îä—ÇÝ’¨Õ‡Ëô”XÓWFp*NL!dd*~ J[q. ÅH‚±DH|=Jm x]\oe Œ]=3>AJH hd>¢gXS&^^Br]/W_Cwo@SS>\a)…­_irSjj0^|L[W-€c5ܺOÕÎ~ڶǘ˞güÿÅU dvœjrŒgD`1“ic[x=^K‰Œc`Yد¾ÿÿàæÿÁ­ý‚€Îa„˜o ‰yÿÿËlÂ@O‚9`y9CH-~ºg1f#9c'@Y)BX%qoh—¿tqGKˆ0mQÓ¦oK€*]’(I‡&kƒ@‹ªS¸Áp{Ndgo»±­ÆÎª›©mˆšSmƒH”za’g{ßÿ‘ÁÉ}ÿÿ«Ú¨w–S…gE`\:ˆeB•®h–ÀkÁݬ«Ï{FB(NU$TdLi{Z‡ÌtÆkt§]r¦`n“NKy9o’Z|¡©âˆ©é‘¥ÒФå{|»Qn’BQs-JU;Mg17R(Uc;df0^r1VfJg‡Z„¡gf˜_y‚_Xh<q_‡£l€™I]{FWB\‰Nx¶S{´[‚µhˆ´UeŽU¸tŽÄm„ªee‡e| XjD[}NbŽf“¼|Œ´f‰Tp}SfYk‹Jlf—§ew•_lxCfrFSyJuŒNfŽC]…Jd€Vn€Xz¦l|£Te‚=Ny]uœk{©kƒ¥cˆ•OmyO^ˆ\it|›fy|^…§©ÿàq…™Sa‹HhƒQeƒVmWamETnTl‡XfHQvgUjGQ`@]b>gtOF7rH,iq?yaL^jEKOC`F6]O+kR.nV/[]:NK7wE.³N-hƒG_KN„ZFP\—vYƒSRx2^p1X….dyKbAsƒRÿ}Qÿ¼Oÿÿ²ÿÿÿÿÿÿÿÿÿÿÿÿÿâÄÿÿ®ÿÿ §ÿҟƧ¶°aÃgyšPš“O¤¹g·uf›mGr_W^]ŽI9n—as—D{’A‡Š6ºY‰©T|¥_”£`rÍw\¦Žjr@~:j„A’KßÓY•ÿ¢Çκøy´óªžß†¿Žp—ql‹\{—cbŒcaU`†Mls5}p0‰Q—©at‘X•{>‰6“{G›x@œ§z€ÀP­vn£a¢‹?œ¦a¨Æ¥¥Ñ £À²XÊuazu‡QW…calDo…Q¿…Z®èŠ…àšÅo‰Èy”Ÿ[w–q£”a²ælh×’jsRŸC^µ„isOu:žWM‡b]h1a¨/–vD¼Î`¯Ú}u¾m¤Jn¬]j^}œNšÀtfÇnx’K„h9–`e^%cr1h6\‘;~„C†«\‚‹[]ŠJT}9^x4}9ižhrtHލRqªqyJªšI}‡nÀ¥[°ñ® ÿ¡½­v©–l`˜y¢jP¾Þ…mÓŠ™ÔQ|¢j—¤K“›UÀ©V±´Xë—‹¤¹ŠÂ¡kÓŠ`¡qdš>‰V{‰h±Za|[s·cq}Nÿ~]¢ÿì’›om?p~¶]|ŒEY½BÙ›0¦Ü„•¼|êÿ~—¹€n·|ưH^ݼuf'¬–rVŒr`v7c|Abn0jr8buL|Mqw6˜Ied!Zc1\QšƒPb¦X€‚BqM‘´W–‡kh’z²ŽUnzœu-`j>Œt2²ÃtÅ„¦¬dÜÍ÷ÿ´_ÿÊY/*a?)\„G”‰J¯î³É׆I¼zn‹L]n.Z|0C9$GF,Ë`3`Šj[:Ba'Jf-IP,Sa6–Y2=T!Y\$…â}Z{Mž„MR«SµqCŒ²l“yg€tUh…DèÂx±³€âº|МWœùT³N—Éq›Øz–¸}ÉèŽÄû—ÄÝr‘óoÓ^SÿùÂËÍ£Ä↢؇“‹SŠSX…¸wÅÛ¬bÿ{ep(»±†bTyœSʉtŠêhr›I™¬«ÖœšÀ|«ã°æç‹ TWj6aR1U]6†aA}\?‰oG[=*\H?vnP’ªmo›N[‡896{žSc}Df‚Jèÿ½–ÿl>\'1Y*'.ˆzXØÿ¤üÿʲø„ÊXr£BopI¡Ä~\œGX’?GS8pVhºñ½ÀhR‘8>n(WŽ@f¦N‘„]²¾TÊÖˆõÞÀÙ¿Š·Sa,`:trU˨£´‡uˆX{¯RbrB¡‡Nwlf¯Ö„ŒÅMopA‹ˆ€ÝݸÿÃÜÿè»ÿäÏÿÝy}}M'Mi7E}/Ed1Ud(Tq2`ƒM}[~²jo¥fsIi–SXŠH_y@S…ZkWq\x–Y}’Uq©Tm˜HY>Yv7AY3lRgt Ãˆ°õ†“Îtoš]_{^d’@Hs1avB~Wl–5>f*JmLs•dv’Vbv6=]9R~S©y°Þ¢¡Æim›X]†Ut¦p‡±q‡­`sŸGgSl–ao—i{p©‡žt†£X]|Rq‘Shk7G[:]{‚Æ»_]xEhtJqyJk…Ss\…¬n’¾i”MYtJf]—U€£[nŒ^{ t†¥hm~XdxMhŠbu­p{®q‡±PhqYvšÓ¬gv’W„•Zr‹Tt‹\x€Q^tMd„Zd…_e‹[f~b7V:-N35?1e3)el2J˜V\oP~p3d“[XwTqJHm>Mb;ag;v„<‚’GžšYž¡Y«|ˆ°‹†¯‰…¡€|iƒg‰^~c~~V†Œ[€iw‹cqpx{^pp[sdH]•€-m§ahƒ]u=žŸX§­^Ž´t§µk›Ã‚p¹ žkäÃ^ÿÿqÿÿÅÿÿÿÿÿÿÍÿÿ«ìÑɽ–„d’}[uZu~IwTŠ”t½¨Té’ЦV¢°X§Àc–©‹Œ–a¾‰UƒžYwS±{7¦­b‡Çx­®vØ¡c˜¥k˜ªS¸ÇŸà¹ŠŸ¦5ˆ}GCisEVqG®eJ­Ö_ ÞÅŠÑyt­’ŠhF„’Hw‰d~aK•unx4ŠvEi¢zf„8›:Lže:t>N_kz%fiQ{<{f¼—TyÀl¡VxÁmŸ£bßÇu«õºiºmxƒ`¦‰W\›mic4^i3b9enB†T…–k‹žV€ŸL¢TzQ‹Ÿ^ž€[k³„y{Ju’Kr›HɧEÁÌŠÕ㵡øÞq§‚|Wge[µ¹PÙù­“ʬ~¢aŒeHÿœEŸÿ¾”ˆ‚ƒZv’K¡§Y»u˺‚ˆ®ˆ‰§cy™[“\ˆ·t[´j›¤E]¤a“/F¦yu}$uŽ>UYa^&9TDpY%Ê[‹ÒŽyÃv§ïO—ÿU›^bŒ8ËF·ÿxb¦e‰‚?j‘Oxo3qžAm£>‰v4“ ]šÂ}s¹rkªAz—E³\œ°c E†µ\dJU~?sh&¥‡O°pO£KjtJx{L“ƒDy±Y‘Ž>àÇhÎÜ¡‚Ò—{®FŒ/{¼Vñ¬MÏùǸ֓Œ¨{¤yhlÄZ‹’HÒ‹hË¢O¬ÿy`uJtA`tBU‡@J@-tY:X]&RY1ˆ;tÿ“˜[rt_nyFá¦T~ÔsT=“„<åRd·nc‚H~‹Yœf©Í ÿÿ¾pb™[d¤ÓÎî ºÕ–Ÿ®X¡¥ƒOd+QO-—–QÙŠ™‚¶i•’}Z5y¼ZÙÚ˜ûÿɯ܊¶ºwÏÿ§˜’]ŠyNÂñÎj‹;†md’¨ƒ¡¬™áþÙÍœ…Êd7h-C3|aCŽaFº‡_^r4l‡>il2¶nuÙd_wBT—1“‡KžÀry”UòÿÔÛÿÑÿÿÿ4W# $,^gXͱÜПéÿ§—ÈZj®CÌfèy‡œiêæÆ½Ú}i•LÑèÂÍ쵞ˣ¼ë£Çÿµf´XTKG޼NwœcÀóŸÑÿ«µõˆg§C€‚Lae?xqFV†A½²…ÏÂz\cBŒ6FE7¡‘sq˜A´žl¦»^Ç¢yΣrÃÜv¨§yÛÄŽñ±r•³vŸÊf}”_s‘L]‘Kyº?§nÀ_…ÁOo’b_ˆXqy|œ¼xdgMr‡K”žoƒ½EW~3\°9R”>]z1Gb*QgB|¡Mhz4BZ,ToM˜Âo‘ÛGSr/bn;r‘a}­aw£cZzEZxK|¤t|–U]_CTv;Tw=[GfuIdzUu•__‡H^Dgv@n“@c“V`ˆQ\}arYf‚bdŠVwŸtˆ¢Qi6Ia;Nj@Ju8Q|4UxC\vLW}:Bd0Ii?q”Qe–m’»“¾è‚†°Cr¥f‹°Zz¦Y¬^}¾P]‹^n˜tЍs–¸o•\™a¹]x³_ˆ–NSkBOtOœ¬–ÌÔky§_yœBUqNp˜T_‹Vfq“¢hy†U|”N_HXxFaŠKX{Hb[mˆN`O[{U\c…§v•³l¡HX_B[vt‘£k¡¨dq|Nf|RomPXkMw{Xu~OWsQ^vORdTO\3,`0%E5B3sHV€4TŠ]bqGF†@Hw\C`DAK+B[1mW-ƒz,~—C{cn‘`w|g‚€]…•]~Žg‰y^rzSjzYnvU{tP~{JskXshTgqYsz[`tt^±nJ½—Lo§fhƒWY_AiQ6JP.e;*YX&UW7dK0lp9{†V„…c©›e”ÑagÃ…LdbaI?‡m)º¥7ƒànl³¨„‚f¨žWÿ™kÿÝqÿÿÕÿÜÏÿѰÿÿèÿÿÿÿÿÿÿÿÐÿÿÿÿÿÿÿÿÿÿÿÿÄÿòoÁ¨qw]ŒwI‹¤I€•T„œe‹¦^»•gŒ”F—•ng“T^qM€c9™‹Q³¨cêíuÿÿ²ÿÿÅÿÿâÿÿüÿÿÿÿÿÿÿÿÿÿÿÿþÿÿšÞñX¬˜?p^MQ:YS5Ys/ex7‡VÚ˜S¸ý”«¿ƒ·yƒ§`¨¤d¶µt£—^§¬a„È^|‘\}¢c{³cqšm‚‚Sweœ…Q¥³~rœ¢g¡p›˜YtÔ}c²bUˆX=xOFH3–WÀÀlèÒÅ™E…¢eL3p2™eI¤[eU3Y„6’{7p˜X‹VMtBMf=A_-Lr*ih7T8Tv,J,Za5º+`µsz[E˜²P›ÏZâ¢t»Ì°~é‰MY‡n0l‰K`]6\n0h-ˆJwfwœT~˜Ky”G¤ \}«p¶Uƒ©’S}†RŒœQ£¥[{äz’yg™ÏÐÐ}{›}LŸky¦˜­¥_‚¾~·—R¾ÿ‚es‰ŽrK“¦Y»³Xµä…^‹p[ƒM‰N®‚T}ªdˆN©‰\¿á‚šµž|À•UkQ´²WË÷‘pò…Žw>;ƒK^q4w0‰¿E~¾_à®M¥ÿ¥µ¦s„òˆzlK¤ª[¥é Øá„Îü¨¹®¬¡¢¤˜™ÃÅ£›ÓŸw „ °on¢€ezYTT6bT*t‚Kp”D€{?n„Lss\£Š8®ÀŽ£BiRˆL9jt]†d7­gu¡Fk¡I‚‰@š[†¼|tœ:U}Hb{VP@I4D<8Lel¶¹bÙ|mÿÿfÿÿ~ÿÿº»ÝŒ„zRY†NmLD\t=Žk;myCZu2l\;Ý–eeE^rE\{=惄†Åd–È^¿·f”Øz™­nS„0w“Y…¬c|¼u±µƒ¶žLx¹Q‚iv›§Žv¡I¦Ý‹­õ[£?D<œ-4Šýxx“Xem>ë\[ÿdzÿÿ»’ΘhNd{3¯Ù¦]5ŽÉU§£w„¥LÊÛ‹¿ýÈ–â…ª·¦”Éxw SO]&dQ1r|;“†L¹³sïåÏÊÿÎzÍl‰ªiqu\¡ô…šÑd’›`¨ÿ‹ÿÿÇÕÅÈû®£ÿ¼*FBR.I<-C=8+Bq€G Ìp¦âpÀǤ¾ÿŸZ¡V¬¦ˆÑã±Ô÷ÀÄÿ©‡Ž°Ù§®Ð›Áæ§3s(HR<ÀìüÿÇÿÿáÿÿñÖû¼Áß–”Ìr]¸B†·^¯­ŽŽ~k38%xFr<¶`ÿú¬Èýu¡²o°zbÔ¨z´¦p’”j“’‡©À{Ÿ¬z{”EYc>gnY~°hœÑ–³Áƒ¢Ý‚²ë’‘Ñmn©aa‡Zco:dlP}xTX…@n‰R‡¼ww´^z›l—Ü]Jr.6J Ve;cq=K\4Tp5a€WšáЧÞv£æk~·K`xGC_8EVDy„PoVn_…‰Beu:a}?^‹Cat1W]9D[4e‰HUv9Lt9fWx”OXxKp{AV|Zf}IdpG_~V}´slž]r˜O]ƒCX†Ov¬d`~FlUs”ZX|.C`3OqNn’Rkžb{«q‡»hr•W¬i…±dÒl¸tˆ¸w–ºy–´r€¯jhžt§s¶s¥â|¢×XZ|KbuTd€`u†lz¨u”Ém}‹>UlHa…MWŽRqJVp;Mh[t]n•JR„6Su:]€Ce‚Tf“a~¢eh‚_k†af„__uPWa5Q]@\…|¢µ‹Ó³cu}NfrAWf:XyM]k^€†Icu?Wu8Db?7T;8Q5CQ2SU+Zh+wn>n„K^’VJ„RXmN8e3MO/JU!S^-qd+s€6p†We‡Sf|Slnªà^‘À¨f¼}jˆ_Žx?™²f›¸u“¶x{›ptuT€…Py£cvžb†ˆSv³]ƒˆfT®P–kM“™eÀœe¡Ý¯„§o’}M[FT<‚X!Ê•E}ë¼o¨ŽM‡v`p/y};~\_Tpo1e•Mb†G`’Pj†=hœ?NvL]^>`b<]UK€Œ6Z’O]jGaa+m~3Úv<ÄÅdoûtSi:\7@S${Z(ˆ[½ZŒ‚Op”KW’A‰˜9{«\m§W`U^kH‹>Œ¹Yf±e}zU_¢QR…Hyg7d’K—8›ÍuÁw°a‡Â\wkZc–mWh:o’®–U‘·w^ŠR¦’@•†ÎÉ‹nȘ‚Ž>ÙÅ_Òî°®²¨V†b„ƒ7‰®E€µY³ÃLƒ¼ZÌÿoqPto¨5už1uŸL~‹\ÉžN¸É›¥ÇÂË{›á«°¡Pm¹´wŸK¢ˆfhŇil7Ti@TW-U\1@<4_c-€k.bb=[o2„AàÀcÿÙˆ«ÿ‡³ùx¦ß†`‘Ck/p¬=ry9s`sm2gÝsZ’14i&2\6#²Åe`›ZVr9{lEb2ÛØyÿÿÓùÿÎuô‹–”V`^J­?‡ô{§Á‡{íjhµJ§§hH¢gQc0~xHwpPhs?p—B²X•½m¥¾iZCj‡AŠœWy¹cmB~ŠQs§gNk2Lm?Re*woB¿äÀåöà‰ü£_¡M-Vàk‚‘µj]>gH%o`FÞ‡„Þ]t?hŒ>`¢AÈçÀõ„š×‰œcíü¼Ž»kйb–µn†Æj†¼o⺔§Á‚‡žUÅ»……»}ÅÀ™ÄеµÐœ¤¹¢‘xÿÿÿßÿÂÅߪÂÿ²ÞÛºiâTŒ¬hïóÆÿÿÕÿÿý‘ÿms¬Il¦4xÅPX‘=x}ÿƵàÿžðÿψßbpWØýÌÊå½áÿÌ€¼díÿÁäÿÆ›Ñz œoõÿÍõÿÙøÿáóÿÄ¡¡|]bJ\UTÏñ½ÐõÀÖýÅÂÿ”²çWp¬+\I2„“_îîºüÚŠ–£m`oA´ti‹ŒZ·ª€­­c†”cš¬bY€&X~:‹†EŽŒc`†J}utÂì–ÒaUnKMT@e}Mq€GlOˆZr¦KaŽ_‡¥uw¦e}¿Si–Xw¬XŒ³[mŒ8]j9~Q„‰UŒ’n}—o‹©kƒœ[{…:]j7jeApMo~JbhCurOt‚Ax{Ap„Gd›=~Ps–He‹J„V‰’Q„…`l~@ktA^f;j‰Xs~=U[C\iY~§~€´p|®jo‘O»|‹ÈaZy;W{T|†USx:NvBl‹kx¡fu©Vq•Lg‡?V|:]‚Mh…]lŠ_b„]w’wަ~ˆ³«Îy†©‚¤Á…•º€‘²mu‰HXqGYxAq€PxƒPhŽZ| VnŽJS„IUvIm‰\eƒM\~@b…T~šk†ªZƒ¨Pm‡6S|B`‡Osan…Obƒ]nˆYe~JgzCZi3PlQ›|¡¯‡Ô¨\f‚G[IStQkŒXƒ„b––Gy{H{˜Vw‰K<_;JVš¬Vs®wi„s‡oV´†R~žcl„pž„NȨRÿ»mÿü†ÿÿõÿÿøÿØ¿ÿÿîÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ±ÿú£§{ˆœt‘j‘k™vkç˜gÿÿƒÿÿ³ÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿõÿÿÝÚæ¯²¡‰œË|…ÿ•qÿ¶otµ•~xR[•pPnSpn:LŠCR_A†uB ¨N©ÉYÏ„ nb¦m”ˆU•½]нz¬©–}¹eR¢llV;ZŽ=i}Lp{Fc†L¯rH†¾b`Ÿ_Š}Q›VœÇuSÅ™3hQZ\a“7om2¶~A˜ÔzpÁŸhƒ}x•LbOˆV]¸cž‚O}Ì\©¯j¬Ëš~Õ“_ŸzXlHRg"d`)„j5‘r>Z|WXH0}c5›y7˰R•û~oœŒjƒ?by1]„5r—1}–HjŽJüªJlÏ¢|˜Ng‰Nc›?^jTp€@m•>¤£C¥Þt„Ë€h“\epBL|L[i$‹™9‘—Ld‹em|C€CK¡hhnAwŸR„´=†¥[l¯m¡i™â›……sƒ Qæ£f‰Ü°[|eŒl5e\9ŽsF|»lžƒNcÃlVf9·¸D­ëœˆÎ—ËËd¸Ì‰[¨v¤0[ D”‡-ˆbF¯t¬|9Þÿ“|¯˜N?H+¨nBa‡a…sA“ʈ¶¾|´â²´½††¿²†¿aÑ»q…ƒZv[ƒ•DS€BNZ6PW#j]2‚“3i>~“=l…<´±ƒ±ã¨Ñá¤×ô„Âúœ¨Ì™—ˆ^C‘YXH!\‡IJ}-ji&x‘o¾‡cMµmD +:Ñÿè\—qK_8HT0}a8½{ç鹿ÿ·È¿p¯¶h™Ìo¶·zÕù½çÿÉóÿáËÿ»«©o[‘W}[tu^mpLx‡Ks›?…£N]¦?gS)¥²VX“Dª„IY‘<‰xTs„>­¢zÁÒ©±ée[‡2_…-ž´ÃÚ³Åo±{…£[…žVl¦gHo=Ji"yeD%KN6•›mëóºüë–tÊNÒø©Øÿ¬žÁŽ½Â¡ÿÿÿÿÿÝËd‹“oÿÿïÿÿÕÿÿÓU\-9M$0HAC“xŠ{yn{rx±¾ ¹Ó³o˜=`h7‡qH»É…¥ˆfîX_9~ Z³Èw’‹Nž¥c°Ër¸ÒaIG0€—>]œÌvZ·Ms@H_NN]6Ka1MT7[Q85d7?I6UMMf'ca:sW.ta8huBWg:kbrs@~g<špD~‡QTxLW]H`qDauBUyCMn5P[6gW5’d1{®A\—jU]JoFX<2eO+gY2hp6yuOnlQƒWPžY5¹”L§â–¹¯ž¬ÂlyÕ‡\¤zLqJYT;j^0‚lB_YfyW‚z2‹K¹_ôÌsÿèŸÿÖ´ÿ©”ÿÿ¯ÿÿÿÿÿÿÿÿÿÿÿèÿÿÿÿÿÿÿÿÿÿéÿÿó»îÅ‹»šî¯wÿòŠÿÿ¼ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿýËÎÒž§ÿŠÿ·zÿÏÿÂÿ°œÿÔ¢Tñ­WdcgY+YvLM‰OQkImt=›™M‚šy•q{½wQ¯qqsH~–@¬ªbvà¹w~y›PLŒfYU6OT1cb4Uf@Sp8¢l- Wh”eyN–¦R‘Ä{UÓ‡frM¡<ÏlÃ}€¯Q˜[’äÊÎw’¦ZµWx¢|†w_‰¹b™­v½Í´¾ÂœÒÀY–‘b`=_Q3}^*wu9tƒ?\€=W/“`РM“ÿy£Š“¾¾oœ³mÅZŒšK¢±rɋžˆ~²hÄzGÒ±v‡ýw¨N‰š@n«X›’T­Å]qžza b„}LL­JFk6jh"j“?T¥PQTN¶†4±ë‚”Í€z¢|o¯`k¡VltLŠqcï¢|‰Ì¿„¼V`ŸX›°Qk»SŽ[PzAZ`0[\,}`,O|F•†$ººu§°c¦Ñ‡Þè¡ÿÒ¦Þa͹M|à±6KY…v$†h[»¶ZEUc°¬6ˆÄ£5nE]<»’=Jÿºio'°‰?©p•¡v£¦ˆ“§n¨«j`³W„·O›>}©Z…šFn4XÀXp`*hc8}Š@}N‘µdµfÞßÿÒ®ÿÿÓÛöÇÍð²šçŒYd'@Ke~%dsDR]1l‘Bvj:aÐwKr,e‡0’ÏPª„Jãô®âÿÆÛÿ¶nÞjp“/™î~¶ÊqÞó¬éó”p¦_”©j—XÍÆ§êÿ×ðÿä¢åÙšUt”NtqF_oGeW6y{Wtq<‡§PW·Md?޼J|„GRu5oR0bm?š—h’°Q¨¬r­è…ÎVj€C·Qxëƒt”bƒƒ~Ž„R•Àl€¥iˆp£ß„ÁeduN>G'¨¸FŒ¤Hm’0¤³”·ÔțȟœÂ‚‹žX‹Âr­Îh¸y›µe”­Q››N¸¨q­»bq´>eªR¤à‡`HÂñ¸…¹mœ­zQk=‰„QµŽ†eœ,f¨3rºKr[WSo;ǵ¢‘»\‰ÅaöÿÆ{øfhB5O[)ƒ™QxDÊ»¼ÌsÒø©ÇÝ£Óô·¹ç—ÖõÒÿÿÿòÿŲÜ|íÿÇÿÿßÿùÆ`uA:FIj+(D1< FJ,Wq>eg/Se?ƒ¥i’ŸzÑÿw›Àn‰¬Qµ¾žm\nZ4ŠN}et„Rˆ–x³ÌަÊpËOduAƒ©iœÔ“ºø‘†ÈqšÕ†šÍ{’ţ匈 ƒ¨ÙŸ–Ó–Ô”¯Þ‘ªä…jƒ[qX¸`g¥KGjKa{k¬Î—¬Ëm}²xŸÉn|;‹x9nq@™]sq@p`Oƒ„lˆ–m•ežÏf‡¿h©¸iÇj‡À`Œ²kv£T€™o‘žrc}>]{@ad@UlI›g—™c}~F\l3Cf*T4>^/Gb;NeBUtD_xK`aBhu\žµi£Êu Çy‡²]m}?ZjA^rS[„i–‘_Œœi›Wss_ˆv1GpA{vAYvCRe;FqAcwBZuXœ¤ank;IRGn…kœk¢“Uv“\o”ToRpŒ`‚Ÿ\h…l–_tmG]uo7M0@F4GV*Q^27b:>UE=H#4A94(N< BO&>P4IP'RY$e[5|Z8xh4|pQwrDqxMugEwh:g~EelJyt=¢q:Œ‚Kw€WW€W`rR]sGYh=ZrBQzLLrG[S:^%m†:L‡eJhP—X7œœ_’Ò†¡žfoÀ{OvLX=eK']r0opCV‹J_pPyv3‘sE³lEÿ¶Xÿł⴩ÿ‘ÿÆvÿÿÑÿÿÿÿÿÿÿÿõÿÿÞÿêÜæÏêÿ—×ÿí¢ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿóÿËãÿÈÃÿí©ÿìÿ¾–ÿµÿÔ¨ÿÿ­ÿÿÁÿÿÈ›ÿæQ²ÅjS"–l@™º[e¸Œ}|RU^‚gU}¥Zs¢db¥hˆS…¿Z±§r}Ñ–ƒ¤go–h_V@t;QU,BS(ZV,j‡6sF]ŠIR€Fp{0v¡HާfŒ©~„šp²U„ªv‘¤gi®]Ù…Zì·•£€qdžf¥urœtižQž@„¾{…´qŸ¡sœ¹{aªRo?wV+n:¦J ¶cß“ZÿÒƒÛ¾¦Ôÿ§mÓÉŸƒP¤»fšÁ‡|‹l„—]ž¥a^Á T†]Xh?„ˆ6ùªkÛÄ‘Ëÿ¶¥ã“h³bo={~P–²dpqn„FI€=sh-‹”C¥±X…³{“·U¤^¹ÐŒžã´¥Èˆ~¾“l–R{—E\™I~v=cvo™B‡‚T±Ï…ŒÏ¡[vis‹NqµQk›>R/iåt ˜MrÆOz…O¦w’¥{i\¢kc¦Â{_Åt~5PkQ´c4vÿ¤‚œG¤Ù‡nª`Uv3·ÙUßó ‰à²~Ü[WƒA…v3œEqzTd™S¬y@y ]²ZŒ»V”£H²³yóª_\gYtp:i?yk=k:¡n£¶}f÷—ʦ5`­w…TDš×”z¢€H–N²+†Áš8U)q^¤…G|,{y5`t-èÃ~ßî³ÉÿªÔñ®êÿйú¤f‚i‘ši’«ŸznI¼¿žg¿jŸŸcg®jYn:c9øàصíêx€IŠe.apBpO?\Ikv6is=ij0‡nDs©c¯‘`æý¨ZµaQh0v7–™NBL.]c0ž©mÇÿò™ItE€@¶²‚iòXLOfx9ˆšYšÀ}¤ˆRªã§{ÀkYQ7XW,a^?xt/¼D¦Ëo¥È ¦×ˆƒ®bx¥xž¸r®Ðˆ…†R—²Ne«?{‰IxxL…«^­³qzÛ`„€eoyL›¸nŒ[̳”¡¸{´è˜£Ø‹¥«”Ù}´Í¤INŒz\]¼?˜¶h¹T¨évåî¼òÿ²‡ÞVVŒ/MW9››}…å^=‹¼M²ÁŒ³ç›žê„ùÕÞÿÿÿºÿ€†ZÛ襬ÞlJ[7%(C\'Œmy´Ýc3hWc-aW4KX$M_.gp@Œ±}¡ß}½÷£›Þ|²ÆŠv JkŸCmŒ2Yh/Y€@•ŽGo¡f–À€°Ý£Õ Ù™®}„}¤ÅÅu‰š…†Ãg„±zŽ°ŽšÔž’Á‰¥×†–¤‹ªb~€Ydscqh€ªlq¯RnžQdb‹_•ºŠÔÄWqeC‘…X¬¢rrv9yqCgmY|‹bwo¤¹xŽ«e¨g–Ç„±çš£ì¦±ð›…ÁKv‘Yt“Vk‘Hf†Bx±Dhwqƒ–dVeIQk=H`2LY.Pb2^j6B^'5L$Ak4Vw@Hg-H`+Ie-Gn*Jb4A6;9B:PDGT(YQ-St3Uf9bl5|h6}|BquYosRflOZZMcX:]y9ZlDƒf8†l4pxNzpQh†PD…aLgW]`6ok6l‰LR‰fKi]``4eW(2c8;H>OV*ax8u€Cq‹Op—aYTLƒlEoPTREˆH,¿k1‡ßu~«…h˜YUyZk^<ƒz:y–KuŒWOˆNYkPaj5ªV6ÿe8ü¿eñ¾–Í¥‹ÿŠÿ¨hÿΓÿòÎÿÿóÿÿòÿæõÆÊÅÿýÿÿ¡ÿÿçÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿýúÿÿÉÿÿÂÿõÏÿðØÿÿÑÿù¬ÿÿ­ÿÿÐÿÿëÿÿ÷ÿÿöÿÿÿ[ÿÿSlu§n+zÙ_C›†UbEXtF}}@y±[¦nu°ltŠmu^™¢v{³XfŠxOz\OhCDa4U^7KP-kb'‚„4—fy”Q¿_xµXs—JZ”f”{Th£|Rv8UW\`u5`nPɘ=šçž¡Èª®Ú‡­Ó³Ø …¶‹šVƒ¦r„€UoŸoœŠl‘Ìoa«di~8j‡C˜xBkŒKt@Û®mÀý©È ~›Ž“Q­˜Y¦moÓsŠMl‡cswl£Rr§nÇK°Ék¥Æs„²‹]ˆ‚qxKh„:}:—xcr³[d”L}‚:{¦Bx¬Qt¦McoDcz@Žw5f†c´ŽD‹­™`¤||9ÒÈvvía‹O“ªG]¬†Oœ4KU&YE7Ê>Ûÿ¹¦ÿÑW‚o‚T1vÈhTA²§O­öwLŒl?9+DJ hO.fxK”_Lg|_xw8ýõkeº¾ž¨^Œ¹·¢m¶¯j»¾’Â¥Œ«ÿ¿hÕ‰Fc9‚`.j=nwFyu>¡’@vžW©­Y­x˜Éj•ŠNV~qsY1Œ®Z™£k¬£VüéˆÓÚxÖÿ¨ªÚæâ£°ñË…Ö‘“L&nf<áw9iWlvc>^#.M)E5CZj"ÏÃ_Æó•Îö¢¯å¨ÈÒ­ã¢jÄ{Dt$™yK:p8D_%di.¦Ó’°XoS_~8H{0Ui4š¿Jx¯O‹r>•zU’¥K›Tu™Df–IŽŒ;u}?rHˆ‰NÅ·ty±JƒE˜¨plLFa^<ˆx>†Ä\Æ{€Kyk*‘’=íÿ®ÿ”F€5h`<…¢Y„Dw¦VvSl_u®69Y—nScÓ9”Ös„l:šŸO}ªCeq;Š‹\s{?m†Qt[;„k]žµ†‘ÀiV•@€›[¡¹r—Þˆ¬£‹hœQ“YVP4—[[oa„q[‘NoˆX›¼Â壧¶~y¥TuœB{ HUf>Žzt‰­c·ÅŠ¡Ñu‚¾T«ÊÁÿ§¢e€}?Á̆‹±fbG¤»n³|£ÿÿ뀳Ok;w§N‰µUG‘(55kMDpx?mVJ€¸Tv”MztB|‹7y”EžŽo×Í´ëè°Þõ˜ÎÿØÿ­¦é—Âáµæÿ£ˆµ6ir<¿üƒ”Ýs¥~—¸‘¢Î›µð­äx•Ä]RiIgnH‡›u}¤d…XxŸi·¸ƒ€¤l‰´O_:f~4uw\||A•QUƒLk…\jO^€H}™]{©ˆ•¥§ktuFŽ‹`Œ²}¡¹bqx8PXOiWnNr˜X•®b±f‹š‹ÆßÊ·Û¼¿Û› Ócw k„ªrŒ¬c|”We…Sz‘]g}Vb}OTa8Ob/Xb*Eb.b€3Nj8G]'Kp>e–9Bo-J\1Og2BY.Fa6ht@RV,HU:bWbŽXu˜[œ¿€ƒ§‘¡Â‘—¹•žÜ‡Îp„¼q†°b¥oœ¯y¢¸oНPYtETm“Ã~½†¶O@T.omHhxO†ƒXo‰Mi‹ZuŒV|˜YsœVq‘Oby#PJ$B`0iS7pf,`xGfwDwu?q‹Io\l„_QsW?ZCNI.OW.WcXd=ff;V|Q>j\2D7B: W?dS.‡k3‘—JŠŸi˜fƒ‹d…‹c’da›Vcw_žm6µ”C¦¶bˆÎ“l®pm˜X‚L]—JIoZHXCH[6CW1n|;cs,NoR=c*dI :ˆµ]¼±jæ›|žna¢aK~T˜i7L¿dAo7•_0W¡R…sE°¨WŒÐ~’µ¥užª†qÁ˜z¡† PVŸXrw@†›Q³¼]É}W¬€Jn6Zn*™w7~ˆB«—=ÓÇaé¦v–Ë…T¥šw³Ÿw¬Äz‚Åv~¬xR¢no‰Atˆh{rUr>’‹U{‹rV¢]IuLig=ކCj§ggˆNrqY]ŒG¢;‰¼uuŸcuªSX’Qdv8c>°“=_¥dM{7wt4»¡V¬ù¯^¢€¢’;‡Ð|…‚YM¡ike'³‚<×í‰âÿÇ¿ÿÃJÚ´c7,—ŽTÇw`ÿÿŒÍóØÒ¸|p®nŽmE›ÃP¦ù{mxaqƒJä¼W«ÿ»†S¯¹}³°³Ør—šmAk_ˆ_+|¯a–¾Zn«]iŒ3cu/X3]„=ƒ`4~„u_™M’<¤¡Vã¶t‘®VcI£œKƒZt£\ž…FÚÄvÇû•ºzžËiž¿ke£‹od[;X9R_q…?K^0E_'0Q-_K[f…+ËX®åkÀúu‡Ð|£¯[›ÒCjA^X.„]Q•V:‚!gn)v‡Jw9u¯ib~AZ‹MªŽAà}_WsX“p8ÏÆi–º’ˆ Z£®V›Âd½»j‡–a€³SyP¬nŠ…Qoƒ;„BOTx|1[2{˜ah´J„¥Uà›JáÞˆÕ÷¨ ª[Òÿ®œ«dÀÜ“¼^»Ì“YÐiXJ/¢vd^>™¹]”¶m¦©xÀ}Áþ­™ô‡td;cR8b`1uÂav¤B`n1ŽnlšP€”bÆ×¢–Èu·ó†gqdc@l~T†‹d±èg~¾W€Ãkw˜ir¥`…žvŸÃ¡^šKw£fe36QFV'…‰\¹À}¡Îq­ÿzßÿ¢¹Õ‰³½ƒ£€}žÍrµÀ½Ë„o¥7”žXŽ‚s£ÙlrŸ3q0k‘4h^G¯‘m›=eu<€¡d³Ç¡­» €…TŽVKƒpQ|‘CTg9LX,fa>W^4|ŽdQZQ‰ss˜¶}ÌÛ¿©®F{ohµåŸ×acwI~•eku®Ú”¬ï‹}‘X‡˜Y‹‚Vƒk‹®u•·u©»{p¢V}’}°ý’ÈW^–AT\GimLŠ—Pw;f…@X|B} Sp€Vz[e‰\€£{|ŠK¤³u„¢rµ³ž¦ÐgqŽUgˆSqŠLs“Gv™e™ªmsuPƒ‡w{–_Us_›ºt‡\ª´‚–°[d{Mj”i‰–MVmM^wGF^7O[7Vu9j‡=j‘\w¸P[y.Z`§Üiu°CPg0GR+BV#=OCH-FA![S$oo3^|MFuTF^K8`L7T@?B;QD5hT;›m@ŸŸM—±h¸r…´{q¤hj“Xi€Mp{CwF_9[v66\7,7*&.` ¢7ÚjLÿ…Vÿ°ÿ¤|ÿÖÿ÷»ÿÿçÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿôýÿÿßÿÿìÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿùÿs‹ËXO‡ÃqL¢òs´®ƒ“Æ—’v{³„cfV‘Qin:¥:[˜Jbc<œ*¸ŸRgÇ€at`|}6J—?P^T^Z-hr'ª=”¨W¨¨qm½Ž`˜hm‡LW’^Š~=_§Ul…Xvš;‹ž^™¬G¦‰l¬¿z–ÏÆ¨R° ¡iwœŽ›¯WT¨i|o:o±Vt”BzžOb©xKs2K]%`l/‚„;ĘAÍâß§ƒˆg©sS’­xµ®tY™k~=l¤\d‚bgm?bvN`oElk:zz>z´nhkfyfw‚V‹˜c²³tt⦟TmšPÅrBsÒ®VuSQZ5†v;`¶¼Z¬Ú‡Š€†‚e[µbé^FyÿÛc©W•‚83RDY!Qr1@w"ˆŸ'L5(.0Fn;%š…ÿÿ¿dÅ¥“¢U2‰V74Dr!@e#/QqN8l’h]¤>l€=l|IJz=­q2R±oOb.{}7ƒ¢E«Ð”yp<žgA‡ D‘¸Oa„¢El’M™’mrUPT)ng<[h0¢^{U”ºwÕØ©\ª:•Yš•\wt]ÿäàÿÿÑ’ã‡yÀaŒ»vŠ·z¡ÑŠk¢Wcd?J{4Cg$Gn)KQ5Œn™½t«†”ÿÿØsµ?z˜GTp/dL:b…5a†)\(o‘0†¤Sw¡3w¡7g7™™`ÓÏkï»x¾‰W»¸ ƒl”FUgI~™F„~DÓ–o·©h¥¼wÆÙoh‚8qVK²¥rƒ—O`a?ƒŽ†ˆŒm}ž[߈œ×všºsÍv£Ö”¶’ Õ§«ã‰„ dt‡IyrLnV}˜Ytc²Á‰Ðj™¶|œØ„ ¹€„«RjxQatbƒ¢UbAŠÇ_ŠÝ]c“;cZ8JW2[[)__,pa1qH†tS[uMThOR]AL`H^XD]k5‚o;©A•µ`˜¥ƒ†´oS³tLdOUQ7Qd;eV?ya5›z?›‡TfxR>eE4B6?;%cA&”X2À~Fÿ­qÿÕ†ÿÿÌÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿóÿÿÿóÿÿßÿÿìÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÆî[y²:7€<29Q7#½V%dÇrˆlbq£X}fS¬mzv_w«^`Ÿjk‰I_z?°h:}­Tu‚pasDLWMj=€˜Ht—Za‘?~CŠ•ByžSbœe||K\›UP€?”u2b®bo”RŽydi®^u‹[HƒI¢_Aµ«‚uΜzvY€¢{s™b¥ˆa£äW’šv¹¬S£Ìqªé|´by–hY?G`2hf¬‚/ŒÍw°¼ƒ¡ÀvŽ•}¨R_…XvpA_Y¼…=xˆ\U‘ic‚CGpv‘Ks©P7Y=a75]•`5%?/!}H@Oï_QA L`'7d(]j>Cd[o£ikp*ûȃˆ½v˜ÆwèØS…¹h|r0reCb‚5^d1mtR,–—nQ’*:P&$14?\i>ÿ¥Ô£ËnŠšU‡¯WgŽ=³WAm o†;„¹Qk”2pƒ5ktA•Ž[Ù°{ÿ¹žÞÄ ÊØ ŠbÎxiÿÔ±ÿÿëÓ¸a¹¨c¨wYŒqÖ±ˆæÏ•Çå—êÈ‚¡¢hs„Kn‹L}™`¤Îx¦¾ž›×„Äí²ºéœ³ßœšÔ¡²¢¶ÊŸ’©}°»`¤>y‚Fv˜@^~GЬq|£RWˆ8fb>[`8jw5p\Ldd@dhGŒ›[›Áh¡i‚£ILŽ:[uGm—`£¤Yƒ¬`†³SžuÀÚ—~´\Œ«aw¦]ˆ§QY`(Xk%=ZBU/HiBm—^n‘]sŸŒÇïÆÏû¸ÊüÀÝÿ“p¡7P‡Jpža…œoŠÃdx±`u¢G`3W^/TZ0SprÑÿ¾¹Ärg~;Qb7mqb^1_d4^b6Qe=XJ>X`67K>C<:[<3oU1€yCŸO¤Yu§vt’wm”b=†i8MJK< Wf&S{<…e2Œ{3qW‡YRmyNneS„c?΋PÿÕƒÿÿ¦ÿÿéÿÿñÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûÿÿäÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÔÿuŒÃCF“1/P,%$Q UOLmGvX8KCu}F‰§H˜±j½z}´w…«zr¯ycžaY€Lw\1n˜Kp•do„H_Š;~|@­ŽE— X[ZŸŒDv¬Kk“KqŠHŠ‘Kb®^W{Ad}2ƒ~:i«fŽ[ˆLb¦rBwIŸR&¦ro«Pe}‚jƒJWŽ\®w_RÓweHާIºËa–¬‚žbmœWXf>R[0o#~¾J€˜«jƒªiªaw§ž²Rk²W|ˆMi™IƒxYr¬[wˆ`YƒKVnO‡k;f¥gw“GŠvUrjSKzITS7hj7[„U~>l–m_œPSeAZ].`dF_vAQr;\q?Ti<¶Š7æû›µÏ½k½‰RuHLy.\‡0I—:€(]œ_x9x„RZrF’}4ÏôrÃíª½ä©Ë׬ˆ¡¡x¤|˜·[¥¿„ãW”Ø¡neJxŸ`™ºRbjdŠxB–×€Ôæ‡bÿÍx¬>i@5ÍÿTÈøÏÿ—·ÓœË|hhKŽƒ]ÿ¬J‡ñ˜p|0ïƒC‰WT²uOoŠO‡g1¥[=¾™c¾¶t“½T˜‹L‹˜GvoV5aAjI+jœ8ðßb¸ÿºWÂ_Dv0Cj"ak:C-V@*+Se&@k+*BW»¢Z¹wŠ™QgÈ]8•(#=("ƒ6-BÄlT8V];\:^H[…0‚‹<ŸÚdŒªY”¸yàÂ\ôÿ¤|–:•ƒZ s›\‘£JtvNdh<^f-lo3z“S¦’H¤©t‡~Bq†6Œ¬_ƒ½T©¸qÌVŽÎF›ÀL‹€Pƒ–E‚¡T²BìÿÛÿÿñŠØxµ~Oº…ˆ€‹F”£IÿÌž³×w¹¹‡²ƒ´ÇŽ|Âs¸~”ty¯k™Š^Øÿ¹ÿÿèöÿ·§¬«qWD‰c“¤\Ôzl|G`^8e{3rŽRi[9€‰X|›U‚©h¬™OpÇLÚ`ÜÊ­öö¿÷Õ¼\²JLn/Qg4HO6iqG8A32R34‘§PUb.z_L@z)Th.|pBd|8ly0„ªFi}9zt?—sOšnT³»lœ­]®“T uZÓ¤o™œLü’†ÿÖ¸ÿñ—£–Z⫇¤ Vv¡GušB‰¼dÑňÐÚ}áÜ–ÈÌ`‡Ow—^y‘ckˆeËØ®«ËžÎüÀ½ó¯½ë«x²ng…Mˆqdš¡{xšQ‹HnˆAGpA~‹[tˆOds;ix+AZ,n:BT#P[!uu5dy=M[-6M!6O/CP>‚`@v~M˜C{”€ƒ¾MyŠi—É“‰µxšœ‚˜¶}x@;["Yr1Ti(9>EŽ»v±pc†IdhÆôÎëÿØÿÿÉÖÿ¡ŸÝ_zŒw®kŸn’Øq›ßw§Úkp™?j`*L\8¸ˆ°[NZ9VgBmˆAp™Ns˜>EX*/;"NM;p‚z¼yt¢ev¬n{«r™u•Âбbm]«bdt1WfHu¥a‰Âsˆ¼[\uDOxMe„Jf{@oŠQ€›nލnƒ–Y|ˆ:WW0YT9\d?Zk/ES,?K&8C!.D1EU=_b9Vd:i{]…©r±YayAJk7Xj@Zfx~Pb^1>_e]@;@OA(jC#Xg2Zb?Oc;FS?OC5PT2WE.FH.W@3\h/ztN„ˆ>v•Zeƒ_^|Ka|WheEktC~tBs‰Ij~W\pOoc=Tf5?^;JN,`R#cm-s^9iX6vP7{k0x•M•ˆW‹Ÿ^w¥y€žlu‹eQ”_QtNqm0‹‘;l´ZjyP”^:zcP€W\‘uZÿ¤kÿÞƒÿÿÄÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿöÿÿóîÿÿëÿÿìÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÍý©œœS†©6Uu274,2"*(7&Ü/ÿ|#²ä¨j‘œ¦kFœÚk‹ÃŒ«Œ“º†ˆ§ˆrŒvrnk„©]r§S‘‡C™¼WiÌ‹~P|–Cz yh‘Kdu@yA„³S—UcJžy6›´kQ·kWr:[u1¯@€«_d¢bxŒHg ct‚XŒŠ>h”u¡j;Gί\dCt€8Ê®VoÛ¢Š›Lƒ©^bnŽz8}rZ`†JSZ?ML'–…)®Žm‹³pŠTwœW¦“[—¹uu³eZ…R~q=KœKj„7q—C]vg^†@OˆL^}6@gPBK.GJ"«\+H™[;X%GT*€ƒ1™µUpŸzPŽOTS3BZ=FM3@])h[*mŽQ=WƒN–x@”ÿurŠlbnVSz9`‚+L/fm)j™I@?rT%ޤXtŒu¥®o^Æo¬¹L¨Ñm´…s[Lo‹s˜sm˜sgi²‚‹o9»Ò‰”À›@š^Zf ¦ÔP²ÂwªÍŒ_Uf»‚9Úé­Îÿµÿ—¢Â‰n‡q}[?9\.ˆW.¹‘Csz[©£E“¥c³F¡\¤‘M•¿a‘Ép°Ÿ^£³R~”SnJU¨5`d0ÖâdÂØ¬Îÿ¡·ÿ·•ㆇȊHoL.U ;79$Y#=1 KiW|#«vUZ¨U£…OÉq±çvÇÿ«W‚3nŸD€‚)`µQk¿>^6þˆD¨ÿ²¼¦Š³Åp‘®h¨ÿ‡¶©u¼ô“Œµ[}VTe6³vF†ƒP–gUƒuX•Œ?…}T©„@©¹dÁ“^{K¸‡OpÂ\\dKšG•½}‘–:œ®B²¬cª¿b—›hÆìŸ©¹gÿÿÿoy[ÿÿ”…ôv‡~E×Ó{ïÚ“ŠÃ{±”`­ºi“Ô€s¬J›À†Ž±_a£i~‹MkSFoŒ‹…}r\6Œ?=j/cnK–¥˜µ‰…§s†ªne†=FL.hJ@ž¡m–߉”Ás»ÿs¢»€¹bžÞsäÿ²Àã°õ‚jB›Û|E`$PY+W^1_:Úáfg©A[p6ª€_|˜Oÿ¦…¥¨^]g9„ŸRW\0~qJŸyQ¦’\È¡{݆{´„bÓŒ`Ï‹|Ý»ÿ։çsÿΡÿ÷‹Õ¼zÿßžÖ²u¥¥VŸS·l¨ÏšÿÿÎ…«T±›vƒ¡f‰ªmnDtŒ^v®t¬ª¦’¾am’WRa6_gA¡Ju|Sbp6^?gxAz–ow™T`k7LX7axCr­[X E4SB.cY2ouH|€QsvUi{SUuYUkW\UK[Q2fZ0Tg8WcDL]AQJ9JP1SO2]F1aU7_8‡E~’btˆZP|caVQa_8[tU7_=*™L,Ÿ®Wy³ifPp‚Pg‚lv†^M–n:h^QE2ta(_ŒIS|Dns;UpAY]Yi{7€”5•«g‹osœPššC~¥cƒ›YpƒJ•†L‡²CbgY3s®?v‹Xq–KZŠSj€6h„U[x]ŒBo–ˆ¶;ˆÙ—u q`‡A·yF™Þ¯Š›d’ŽS¢‚Q«MX€d±^-‰•c‘GYœUvYGk|<š„BtV¡ƒT¼¤{‡¹fes„BlŒC`ˆMtnGvS\‡Gc~BY—IiG}7:P,YMPq4Ii0Y{(di:‹H—wnv yY‰VMT/Ma0^|.Š€=[•aX…ÃÕy”逗Åkd¤_†„?xn<ÙfÍŒ^ŸÎ~¨¨iº“w¢ÿ³Šý„}Ÿ@º8Y«J–ÙJ„½~Ýß}Êê¸È°¯ËÙ©³îžqÑv=™='M8>+gS6CMl!@fTv!O†.¬Â‘šÞ—»ûª äƒšÉy‰´\¡X¥×–¦]•‘AºY©¹[ؤR…·VœK½²f¾ÁyÖù£±¶sš¼qNK+{8lzF¡zW¨¬aŽ™P§ºQ¬ƒf¨nR‡ÊsšÕmÕºVظe¨¦]d‚?’H±°u‰¼woHvŽV}P{˜Y¡Ã˜îÿúqéYYƒ,|`Ic~Q{TY”mLëÆ‹^§E@^%FH/‹{k…xažž|lOPK)?C$[aGçë²îáÒu´ePs4ifGoKIZ+IT)`_.pD‰½_wžD»K‡]›Ê–Æv¦iq‚M]„A±€i½œn|zNjl:m€B„›O|«Z¹­m½¶uš\¤…\¶‘sÏ‘tŸ{VìÅ~ÐÑy´Çrðã¶±ÈuƒµY¦YÆžl ­qVn@y£`œ£~»ä’®×y–œe“½€½ï­ƒ§Kaƒ=…™l{‚g•ÖW@n'Kj@ˆÈnŸá‰‹×icJ”­pšÂONr<‚]rxP¥af‰Q‚Æ‹Æ~€–`l„^t›x¿|޳­wÊw…Ñt{¸c]„9Qj>c†FruNƒœƒž¯]r‰P \~žUSˆ:Z{Lp‡L¯“U}­DiEjw]t”p’¤¤×ßáÿÿâÓø‡z‡1:/#>7([^5Ou.@S5JV3KN8_yU˜£c`\Ck`?bg9moRŒ}[z‰™¯m“¥g…r6^oG^oFl‹Xz³Nq©VZCPjErƒ^ixOb‚6U~>`Svªoz¨kÓ{˜>c†ëÂxŽWl¦Sd“BQt@aq9RM'\T2\c2XR-DD(7K*AT3FO8]mPa„KTn6Mf=Z]:khUA\`DaM]9T^BZhMViDmi†zFˆzQ~™3p‰`ƒAoC~vZk‚He‰Dk€>c–Q‹VÄj}ć§ÀGmÇbdži”…Q ºVr‹puR„Z.ˆ|O²“Zp§[~p;”šR¥¥pešha~?jj;®g8f–aƒJ¥§[¤iz°…OŠPPh4x˜Ug‡bbdC‰jEizVUgCv“As£jo\NopCyqDlsIf Ezn7a¤cP€IX€4g~7™rHKung)žc0fƒe\|1["L‰9Pi+Ft6Uk'Tl6zu87‰PS:%ph/f‡0Áb=i﬈dFdÂe¶‘@}Še\b_xDN•O¶}@Çþ½Er–j`'¨ŽE{’ýk”gb9lV.¾NœÄ—»ŠUwÒ”|9½V¦¡nŸÊr¥©wt´i´–EÓæ‚¥©…‰Ö{˜«n›Ê†§¤`ìÐnÌÿû\¯}]x6sW;l„TG§[;<A@52B0`4·^r–u|a{/.4E7UC$=L MlTh"pr'„ÍS–Ñz¦Ö{¡”P3@#macŒ†H¦Â}­ËªœÁ˜“Ɉ•½|xšK|L}­y›Çr¿ñ³æï½÷ÿÛÌÿ±’ó„Th,fY!Ç›Záò©ÚÂŒÙý­ºó©²üˆÉ ZÈÁsÅܵ±Ñ¢Ÿ¥°©…dºh Äz—˜N’D‹˜q ž[…ŽbØ’`±åjÀþʲ¿ ­Ë—¸§“ƒ„WgHzK8¨¬“¦®‘|µƒwŒW_g6Ts=²|ÿÿíäÿë™ÿŠYf3•p‚€Aº”u¼ý‘ƒÈXzµQEL,}¾_oiEXN3mG1 cK¡¥ZynV‡M>dG1ƒu>¡²aI£7 £u‘’XuòWxuPÍû½³Ø™È|‹­qsvS‹[Ÿ¯ƒ§Ù•j›Ubz=›^«~XdsU\;e[=noGpiAodNit\|—ˆ¬ìvu™2ESO|†TiYqOk{GQ^+KX(@U4QuBWŠBk”Xy¯„ĊˤØõƒr„H”™†¨‘^¡©j•Îry®Zy†LbzAXm7[n;Xb5bT1Va/cc1`V+BN?QaVo~Q`oFhrKsf:QYFvvU’™LrŒNe‡N_…RcS_„>^\HhJe[9tY;G&E\Lfua|¤kŠÀrŒÇasCS`BUuHOl@NV'GC,K[-MX1[^0Jn:QlKT^FS]:†X4„‹:Šž]}œbeŽmZuamb?pŽIuŽNhmPkNDsW4{`8‚yG€_zlT…tNpxK‚jKh€IPfOGS:>M0@<(Q5fB.hF*c\4][6fc5uL4sl;}YHc?“lKolJGZRWO6df)blEpn>wŒJy}Mt‰d‡`’‹Yœªsÿ‡ÿÿ›ÿÿÝÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿæÿÿÿÚÿÿßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿáÿÿ³»çŠ‘€7de'.<*((7}#ÿG"ÿ£]ÿÂ¥ÿû»ÿº¼ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿëȟ˸{™hŠ’Gr„FYdN_Q8_`F]aMdF}`n”Q©†N«¿x‹×ŠsÄn«‹He«qŒH]RiwQ›J-—|<—k\‹…Vˆ£W“Žc}¬swqZijDOo>dv5w{8t¤L®Â^›¢k¥µzj­ƒkPpvHht;`s7cxa“CA]¬auBTŽRir0u‘=¸ ]¥›‚|tFJ°`yv6c”À‰‰Žv{˜x‡j<{šqcŽIn¶Kao1“¼dp³pµ¥N¬²lŒˆP×nMxb0=$IE)+<,1g-6GUn'Rƒ.ij'º«š˜Ð–tŸS—¥P(? BK ™U‰³u]£|=B*ˆ†wcÍqq›SI~KŒo9¸}ÝÖ˜á÷±îÿÕ¾ñ¯·äžN‘OU”<]S0diGbt-¯hÏȤÞóŸɀ¤¯nœ`•¥šhŠA–”V[mA’‡b‚pVžÑ}†Ëx„žJŽºN¨·rÐêԜߣÊZ•e©mU†Ïƒ`ŸVj…O\›Fz|D|§e~ƒH´_³ x|Àc÷ÛØÿÿÿóÿùÇÿº{È_´É„¤¬p˜ÁŒ¥O˜ÎV¾ð˜–·y“²[Š•Y ÊfÃÿŽšR‡xFœ£YrËUª||¤žƒ˜ð{³å˜~´L}žPµxˆ”c¶Â¦¤Ï…°ØzµdwY”ÅŠÔ꣔Pf˜E˜¢hiw@ÿ”‡sLqs?€“dc~N_–NkŠa‡ qž¤x„˜Hz¬[„šUÓØ}ÿñ˜ÿþ˽bdpF®•}ÈÚ ¼äŸÆä°¾êžžº‚›¿€»lSnP÷«žÔX†uDœ®htŽB˜¯ŽýèÍìê¥ÅÙÆãâ¹ÂØ´äÖãÚõ«Òç¿Ñð£°qµÚ€•ÌŽ°åx®[f¨I‚©s­Ààÿ³ÍÿŠàÿÌÿÿâÿÿ¹¡ôx^…Oˆ¿‹µå¼œÕtk†`šÅ–¾ÿ°Ó©Íÿœ~¹Q“£n¸¾lž´q—·¢Æ••Ç„¨Ð‘šÖ¼ÒŠˆNw€Lg_(2A/c~WŸ[…š›¹~¨Ð}¤Ï\f}+j†Kj’QlŠe›´rlrH’ŽPgˆHspFulR„_‚©pšÏž¹Ù_j}/IHK…MbvHdc0FP)NM5Q\1D[<]~Gb‚Ug”c¦…¢y‡ž¢ËÛ_QtAF1J`cBnˆEbvS}n>vGx„ZyˆZÄ¢gÿÔyÿÿ³ÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿïÿÿôÛÿÿÕÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿxÑÿ\Pv,F>!04!!#"-"g"åKúµVÈБ˜½’ÿ‚zÿù‰ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿúÿÔœÿû£ƒñ @†f@J:<3$>>$?W)T])›R+™Brªc\‹m>d@[@4€a)€€T_t^flBYkA`s;pv2cŠˆc9’ªY}¥nˆ˜`¨k¸uVa‹Y\tKs‘9ÿ´LËÿÀ}žÆaœfT€D€pDm¡a§šYÁ»f«Ñwh®©sxN„uSz’S|QUÂmLqHGL0b'p©p–Q|ngD:[L@*Vg/XV4Ti3‹p-’²|¥~hw£‹|”IZLpc9T‡MP[8]l0>b=/J#NNR{&Z€˜s7b_Ÿt?º¨‚ `CgNWR/Ue%]g1ˆŽLV—OZ:`1˜Ã@\¥ƒvŽKžƒg“Z¤¨]‘Y½«V_tdƒÜ}O|4aK8ƒ*—G“â„:f(If"H^Ct)JE{]g_hTž¬O/G"^Q&y“P@mI5# ,#j6j{QguHYW4¸€…ºcË¿ÐÿëàÿÕ¬ð°ŸÐ‹a¡_;C%AVCX&OY-ct-ju'““Oy»h€”C}Li“Ff•6‚s2fŸ`]XGhy8œ¾±Ã”ª®il§ZIx.ƒxd±Íˆ¸ä’rØp¤WŠÌ„Èw‡¤a{ŸrU|LiHGf‚A•…dΪ§¥Ù³Ê“ÿä×ýÿÿ¯ë­xOq ]ˆ†[ƒ·Rt«JÈÜœX…PYO9ed;oe@íÿºoxAƒtM²©Xku;ÃÀsœÜdeO@öÿÔÎÿƧÇjºÇ•¹û“^€7loI^Z:ºÌ¤³ÇŒÁô§’¼xjvC®]hTq·T›«‰Äæ´Ž¼xŸ`L}6WlE†œtƒ˜p¡¢‚všf‚›fÈ÷´‘ªtÉΓܰÑΧœ ]fb¦ÈÈõ§Ñ姼ȔŽÁk—r«†„‡}d}JYqcßã°rÂKF_7iuDya_\NcQ[¤‡žÉ¡ÚﺒÇxš¯†œ°‡²Ä¤Ï†ªÃ‹—¶•ŸÅ™Ð|ŠÍx’Òp˜Ô„ìÿªáò¯âä´èê¸ôÿÄðÿ¯S˜:QYbŒ ›ªÈš¢ÀŒ¹Ý®Øÿ¿½ÝÖíÿλé~¹¦[p‰Dma€‡YNp]‚ y’°‘™Ì‡È^wŸX‡†M€o9N_4U‚Vs˜X‰Ÿcl¡t•·¤¤º[Vg+Vw0Wt/i|VŽ…RmXŒ—oƒœXŒ‰Q€‘[¶¡f|ˆi”°j~‘IUe3Z]:bCUYI`{Oa{E[n9bh>_uAauFepGlzHcvKP`ELuw›·WjŠLkPc…Md…Z`€L]iN|dBpfOfo_‰¤pš©[{˜Og|8Zb9lv,D_%Fp2Q^7d\@unQƒ}\qy^kƒV]}Lb~b‹žl§mv—nqž^i…Ur’b‹¤Uv¤Urœ^ŒsIbW<^aNqoL 2E&6M:l‡8LŠKHYLOH,kW%cyEKpaKdP[Q?ug2i~?huJVrIhXLeyCnƒL€‹Nn‰YdfS^\7a^;uj=c;zhBlI¢uK¢²XsÍ…zy€ˆˆE|˜Xb€_eQEWW=qY9Up9sGAj[.vVCoX=jUHw`9uƒ;ƒ‚F–}E‹ŠLy‹WmsU‘kG­’=ÿÅsÿÿˆÿÿÓÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿîÿÿõÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿIËÿ)=·X!(7A!!30&"2#>1];„K ¦{N““r‰Ÿ†ÛobÿˆPÿá§ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÓÿÿÞÿÿê¦ÿÀ]¹~P‚ E`Ÿ\¯˜N‘ß}z¾uY‡T=h:JJ0§[+Œ¦GIŒf¨Q3¤~>’‡[‚ƒLr„?z…?±‚@Â|µ¡f˜³wº fŒ·tyfwƒTä¦U¬¬bg·|—zHr²g©€Jm½qmPU‹Nw_3„—ŒTf[$nˆAb’a€oR^žqZpZft:pp?—sIe½qudYj™]}†K²wIŒÜ®[uVrV9mh@xgC{€Q“šTW}iŒ_+Uƒe^V:…s5]eOkU9V‘Neh?\p?D‘?NV$1Y/KQc†0@}5{U%…œIƒ±_M‹dbb+tKAZ<ƒÈÛÇ–c‘GbK–²–µ¡“ŠU‹‡P‘}`\“E…Àpb”C³›ˆi–9UAL®qŒ|¢\¯½‹®Ù–°æ£ÁçÄÏÿ¾ßþ³›â…ªôŽ»è£¶Ø|^ˆNo’h…˜tOi’PjqxÕû–Ÿ´eƒJ‚°ZMi4IpL˜Âz¦ˆ§Ô‘‘²\zŸ`ˆ§oŸz¬¿‹°Ç–¡Î™¯å•¯ì•߉¦ï‘•ÊmOw2Ep3T8H~?hx^£…nGS9N†D\‚^ƒ»q}±Š¬Ò¨ÀÉ¥«ÍÍÞÿÒ¼ßn‹£\‰‰b«’^e bq·QU‹T\ˆo°”Àß‘~¨kšÃ† Ê‚cMks\Žªl†¤l­iu …w;\k8Ne4\i4\`9dcAle-caF~cP’’\z«Ok˜CXMj‡VeŒK—PbŽLg‡BvrQkjY`|PZyMpŒLa‡=G[6bd:_w>Xi0McC_…€š°Xhdz«VoŸUa Zo˜Pq†V”Ccq@T~bw³t„²u‡«lxˆA^mYd1Si8Y`Csq?v{IhvOvƒQ[Œf~rO{eEƒI„€T}zJxvI‰K´oA¤À[€º€¢—{’´`s¿wzvgviGƒoA‚{AxG_?•i;‹iI{eGqgM•e@©›F¢ŸaŒ`~’Z§„b¼›eÿºtÿðƒÿÿ¾ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¬áÿR{æ7OŠ"0B!D=,%1*+*]/P` 7I/˜c#Tÿ†Ly¸|2R>_w$d¯hŠ‘A{¼Hm›?®Ölv¡YmŽJˆ«LÁÍb‰G†š@³³QïÿµâÿÐåÿ½鲤å»Ír–fµpµÚ€¸îȸƃÊôèɒ‹Á{§g›VÂÿÆÕóµ‹ÝŸ[Äaw|C>g%E[$[y,˜~MáÁ˜âÿ×ÿÿÿ»ÿ£Q–D»Ç§¢ë­Ñ|»Ùœ’Æm{Zw“[h‡LO›A^`,{d?™hÿÿÌÈÿ©¿ßŠŒÏyêÿǯÿ°vŸU³ÜÃɘßð׿æÇMk2e‚7åwt°ÔlªtP¢_Enj:”zP€zE{Iرn¢Ëpd9]8{›S„’Pa^4j\Ek€FQv5j~Ds„M®¯}l¥Fe„?—«kgE´€€‡a®€…y}C‰VEœ–X\~BŸ¶‘¥r¡t—éhoaE~’IuC}}T•Ê~ÆèŸêÏÒïÿÑÈࢹä´ÿœ­íŽŸÒ†ˆ×xœäi¬HpvFt{W\K–‰Ž¬ÜmR¥ÂxÓݶ¨Î‹y•Z`e_¥Çz‚¾Xz£[o™[u¡NnŒR;P=‚¢rаej•M‰„v£¶oBk+V„Y¶n’¾€•PMs-Cm;P†K‘´‘Çÿˆ‹Ýj”Ƀ‚Ëuwˆ£Ó¤¢Ó  m‡®x€‘Ym‘\¤Ê…ˆÙ€|»w~¬ˆ‹£š¸à•‘¸¦ã¸Ãð¤lŸFLwCa{Ty”i…¬g{¯c`A]q9Vb@dwA]\BkˆVeŽS‘Åv²^œŸeÑcy®hy¬i}›Xw™X€°}Ìtˆ½\{EokX\pO^vMržd}‰5\l6Qz?b8D45C76@3;8&=='XK,h\+mxI^rBckBwd>‚’InžZnyoowVZ…gqfa^d"$%!*)40U:RS$5R;:H5AK{\*°Gq¦}`w}s]Iÿ‡>ÿ¾eÿãÅÿýÞÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÆÿÿ½ÿÿÖÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿüÿÿùÿÿÿÿÿÿÿÿÊÿÿ¬ÒÅ•¯U• g•Gi‘vvŒ:Ž•K¨žg“²’¡l… `‡Œo“ša”Šqt²oŠ«WfM©„E{¦g³xdF‹oC[5_\%^`>RaAgj8l}TyHfyaJXCj6d_.ˆpBšlc¥w„דgÿæŸiúõ¿–W€Ò”YcrŸhÂw]l&=a:m=0•l;¢nU»Q;‘Mh%"4oqTV}/ce02A9\3u¥jšÅªÑ‘¶zs®Xn¬hɃ¨ÔœÇ쮾ߥ±w¡ÈŽªÏŽ†¦o¡Äž¥Ë|r„_v«ms¦n}®z¦Üˆ¤Íˆ›á‚ƒ n’{¦·€º±ð“ƒ¶urMVlDit–vH„¡Rb i]wuWNLY\EgUGV\4_j=kX9qR6}bAƒlCŒ‰P‘©^µf{¸‚…g†™jŒ‘fÆŽ`¼W³ o¢ˆgÊYÄ¢\³eÅÛs˜Â­qd†MýÀnÿìƒÿÿ¤ÿÿ×ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿŒ½ÿDWÀ_>mz^@s‡^|Œcp¥d0t!.K * 7*`¯N|A?k5IX1;I1ZD(V^6zi>Ùœ`jÖÞ€{UdayW ŒQ‚°ey€\ISxv.Œ}Slf_p€NnzF±­A3Á“=_)jZ#mŸJQ’Cwp0p¨Q‚~Yaˆfap8[‰8Œe/O¥v€|0˜ƒb«ÿ£\Ž~\‡“=–™]’Ôy±·}ŠØ‰s~Ctº]T‚³V’ŽEʰ…^‹[¦‹=šìžs†U«Óržèx—ÇŠh’`nIq—P¥ QÇ®¤µÍ©²¿¦ƒÇ†š`jÍ€GZ.LG!bR%·tK¤¾[¡LâÙŽw£l`¸p‡Im§Kg†3xªR¶¼x¾éš˜ÿ®ÁÅ…êÿ¼Ãÿ¯Ÿê†¹Þ—ïóª¿ÿ¸Ä㢤ñ­šÊˆÿ£áÿ¹–ÝŠ_L–¼†Š¨z’®r—ÊbJ ¹Œ–|OfwG}eHdŒ=•ˆL\k?Oi:My.Pu(x?±õÿÿâ´ÿ¯o¯BˆÆ]rNFƒ5'44Wÿÿÿe@vnLTf,µ`¶ÿx…£WÜžžjž¹tžÄmp±Av›Gg…8‹…gh£H_jHe„?‰¼WÚÿŽ«ß~°ªaþÈ~ν}n–JšœSÖž]絃w|3m8j‚6vE`tEƒ†Q𪒗yl·¼©—o„Š>‘De„8Vr-]y3gu4΀OI&h<>ñ¿ºøÃ»— ‡Š´Tš’P“Y¼Ây¢Ø{óÿÈ·è°Ó‘ÜÒ±þÿÒüÿ·Æÿƒ§¨g€†dz–d\i=T‚8z§u¯ÔŸ—¿‘°}ÁÒªÏï’O}1Ip,VhBbsHˆ—TÂÉŒÍz¡È…ÿ·•¡Ípwœ]am9YVC‰ŠVQ|'%:!0BH,Be$C^ E[0s„^Œ¸€»ß¤¤ÞŽ»Í›–±m”Ÿ|°Ê¥Ð››Ê˜¨Ý‡W‚JlgzŒH:TG¡·ƒ}’S_e;Pg5Bb3Pf[u­UNjE}—XuƒGgŒc‰Âq¤{Å硤އd@Fk6Eg2SyDo‚pš¶n–¹`ŽÂOg‡Et‰Pn›tŠ·ž©Î±±Ñ“™ÀУÚx”¼¢ÍŒ”¸o€¨„žÄœ°|Œ¤|–¸vÎtŠ¿Yq¢Xu|•ʆ¡ÙŸÇÝ‹›ÀbvŸHc:Kscz™Z‚”oˆ«}¼v Æoz°s‚½gp™O[}DfqK\‚Qgar‰U\…o¢¼‡Â†»r|¥u‰£ab‘YZw]frh‡Tu“Z•Œ?Zf,Ns(Js/P{?H}47_F_~TkšKc›Uh‚Nfy@XpA`oOWzRlp@jyPsi|•fn—Sb}@2' R,_Snu4…|@ÙVˆ·Xoo\}]dgSqiBxjIpoOO^>a__4l]$…i>v}Z“\¨àlm®M›Uj4tyF‡¯O¤l…²€YŠngf@v^A[mNeiB‘ŽB¦kq oi–^k{F›oHL_YO3[]l¬hÔ‡JyÿÑr”ZX¶Q°w3i–~ahHvIiu>|rFÿ„T£ØÞ„É© fw™l†¬i޽j•É}¶M|XhT#pÃF‰ŸGr¥^ot:°žG¾àŠ˜ÄŽ„w¤Êxž¿oÝÞŒ¢º‹xž‰kz:ĈJ¥Ç®ÉzËÿ§úÿšÃÿçlÂxm”K¢®P¼a}¬`‡ºx|}FSv3\eCŒŒOް…j·l­¿o¢Ú¢ˆ²pŒ„F«X§¹`¨“OÀÔ„»Åt‡±Lq˜Gy¬l•ÍÅÌŠwÌ©Xr5ÉfYÜÿûƒí‰Ÿœ`Åë¤xÄvo¸E¸¦…’´GÿÿØÊÿ¬KoMvkCg–M{nZ§–YËÿª†ýyM7IJ&VG#OH#_FomCBp,Ik3AT#`L6oaC²²ŠéÿÁœó}ÊXˆÅ?hJdxH?.de3ÿÿÿg‰DžÄ{ŽM£¯xÿá©rÃpr¥j´Îde?’­f~ÏNe4am-R›3ŠâeºÖ€ƒ§h¬šƒ‚ªfºÖ˜½×ŸøÿÕáÿ×´ò¢Àµ¡x½ªw¢wX¯ÔuƒzG`‹8la@„ƒJxœNy¢R¹¤|‘Wr€A•ˆFc„3ly:dœAMf.pg>a©C‰‡UÿÆÁ[F-fK@™eI^%ok>‹‚Z³§|ÙÁ°à¿­éÿ®²ë~ðÝÅüÿƭш€”L‹DCY#FQ(l‹Lx‡^{yYŒšf±¿—¨×¢¤Íymaƒ?Ss>PeA’‰Y˜«Vy|¡´Ž¬á¨ÂÔ™„¦YZ{JЬU•]EŒ(*:-I%0U&OtITxD7U#)E*cWc©¤—Ž©m]€TuxOqU}w—¹p™q»Ñ‚}•\WqIp‘[s¢SSm8Sq3^†Hy°d{©G`w]„•L^ƒ:Tp-Fb,FcDu¤z‡Ë† Ö—ŸÖƒ¥Òp‡Ïft¯DRˆ=On?KbB…’€Ø}Æj‚¦e¢³ˆ“¼“¡ã°è–³ø‚ é}Énr˜a`Ywže®‰ªu‡§q‘©v†šo±v}©`xše¶”Þ“žÒ€{ª]\{`v¤`}Ã[o£qq•\fuI_yWvŒx„·{ˆÇ‘ºrx›[bjF\|Y¦dƒ¶`qœav¯ª{†£„޳…ˆµ‚Ž®sša†¤Qt‰Q}…Ij‚Usƒ?Zs3Hc(DmCc—ZkŽMkšQ]H`†Yo£acˆWiƒFa{BQsIWtDZp=P_A]iQbtRX|U^„?E0>Y:!XV%]^9€j<ÙxJ…§Zki[zaMmYSWGUJ4POsV<|;|«\e¢qiu\s|C‹‰N’Ÿ_z²mqŽmq^œ}c…¨uoy~g}rFˆ_LnpMƒb^Ç~OâÍpë÷’ÿú­ÿÿÈÿÿÛÿÿàÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ³µûakÊVNMT7:@;)2/5%**F* „Br‚E-tn-.H6.59"6F*-C+P7 aO%TaMfTQh[G7WE!E5&BX,li9~n2œ_Jÿ…Nÿì‡ÿÿÐÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿõÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÂÿ÷…sŠ{‰U“Q‡ŸZW‘Y‰n=h™\UuS};Ÿ]»“_°rs|O~ŽI]€FZt>oa6±ƒV}¢aU‚G\h=Bn@;`*O='?G&?F'V]3kv4WtU>k:yY&V}Sao8Ee9d+±©T’º}nœ„ihŠza}·tn¯`—¤N‰¶Š’Êmm mqtLcvh>–iBˆK`¡gÿ‡I…ÿå|‡fVjR¥u'S™rM^.i‰ŒÈxa\—‡<°Á`»¤tÓ¾”¿¶‰­˜[Åvƒ°s“”iD‡erY0^v@Œ±W×ô…°¹™Ï k¿íБ|zŸVj“B–£Ru³^p¤SkJGl:Z‘5§E†¸l”­kŒ£qy®dz¥fo—F–¾a¢½f•Õ…¶‹@÷ê…¦üŒÍn…ŽM™ˆKà’…ËŽ\“RA~79T%ž]$}ØžwVigR_'wŒHœ>صQîÿžÍ´wrb?¡eU¡][\0¢ß Øû©œñ·G“JEC)QE$>N"¯?.}qQ‡3=al0éX^,|Çm[H'ž¢W³Éu˜Ã‚k¡NVr0§_g0t'‘|NÜÿÿ‚yY˜œ†¹•]‘U¡Ó|¨ãˆºâ§Mo8z‘Ao—E~ŒBlÂ=~–9ÅÞŠÑÿ×ÿ°gŽC€ºb”ÍZªëƒb“LqlE±€^ãg§•wùѨ½³†±y‰ŒYt>ov7prdVyœy“±x‡·uЏhb¡Xx¼^³f‡ÅuÈ{†¡`\vGSzs‰Ä‘œÇ‡·u~¦s¤`„~MapBUhHiw9Ja*=[3AnQaŸZ`—j`ŸLJp@Oyj{žnxŸXxžVe‰QiŒNDtNb;CX:IdBOlFMmL[`.JK,P@2aX,cr6bd7J^BQR=MT4\Q6^[,pY6pn8jO—fO”¥Io¯‰L„gORul3xTybw‡Yucw|Nue@jnO_iVuiE|‡>[uSmNRàxCÿåmÿÿ´ÿÿåÿÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿËÿüQƒÿ>8ƒG/8^6)GP3=;&0K=4.!14)= 0155*.'"+*<"[= Z\57\<7G2=D#1J(F>#<9!C7,LE%)[34/'o)Sr0J1ÿŒCÿÿšÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿåÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÁÿÿhž¼juLh6n«Wi~[qc9r‚K™Qy•s‡£i¸«k„±uw»[]‘Phx>B|K]M'ku5nrQruSl|\SuMGt1@K-[[-Va9Mh7‚u-TuSTl;^e.Tf:Zm7Dq^œ?Mq=Il8jt2o‰=hO§W=ÓñŽQŸuðŽO|ÿ¼s‰]š‡cnkŒUL?—ž<ʵoγŒ‚ŽykiuL¹¶nœ‘xhOq8dFu“T…Êhm—;j¦B”‘Xƒ›sMrKUX!„^::/1*h+\p1MkG•R%ü©Aÿÿzÿÿçÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿüÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ„çÑ^’fwUE•”Ba‰x®9rÅhj€n‹„L™‘\w_iƒgh˜G˜yI{‘[Y{X^|Kkq:I…XcfDfIl vx‘n`kX^gA[g7UnAay4^kE?r2NT'Vg2P|GMi>]y?_m:m”Peik_FŒ…I²Ïp˜ä¥m¶op“LUŒHš”A^|uc_HOj:cl2‹ŠF—šob«W„FJu7,:Bx\&ŸÇgt•†ztXf‡pUNCTQ7iWAFj@QR#´ÅR…†‹p†`©‰PPnbOa0Et?nd+~—M– bð†OŒÜÊVnẄCÀؽT°†1T.[_'It@rw6‹Ñi†jKj›mchOÁšM_à½Ta2p}3°»c‡Ä“¶Ò‚t…hpƒ=Zt;f…=:^7I_%8U ;IXy/khB‚‡Og Jg4tN[9’‰Rl»ƒg‹4V0¦Ô~¢Z‰°{wŸe‰”Pm£L]{>}{6}†O¡I|ŸY¬yR’¯d] MKO)Bx5r|>vy4a‡;jjJ˜§rtš]–nS}ÉQpBJATY%–pP¨§L§¹‡ƒOQmEs˜G™¾h‡Ïo½c„Ö•L—>;`#]T+x;|f9ŒM¡Ï{zpC–§|¦Ø—±ëŽŒÄ‡^x<гdÿÿ“®ÿ’”–Aꡈÿÿÿ¿ÿ¤£~LîÿÊOEYK4œ¨g¥»”bN-ÀpevrJ™˜wµ¥‡€ªY`x8Sj U{)Jb!ƒƒH˜¿{ã乪ןހžÙ‚¡ò‰†¿q“ŠbY£B~fDÁ¸q½ßxÁÝ’˜ÛtbCiyA‹X¼›y¯Œv·h´³w¡—lš|S™`’˜T€yMÃÄÆ¾™ÿÒÃáô´Èÿ¹¯ˆÿÔŸÑÀ‘V¥=Ko2V{;Vq;q“TXŽ:HC,“eaP2Hj#RT&o“.i›.S‰S±Ä—–±cgˆ?Hf+jnEfn:¥sÖó«ÉÿŸ€³f®y’Šeœ¨“¢‡Är‹Ù’µå‡Œ­Yax>GRB›}d ¡s€£aŠv’¿wµÓl²«‘ÐÿµÌÿxK’5wjc‹¹aP’>EHo¶Z„Äm…ÈUT”?\}:Gp.JgW“§g‚¦\f>T~-Pm=j–9apAkTdœV¦³š¸Ë~~–]‹®z¡½~™§aYpB\€Ll›MUŒYu˜…­°Œ \VlIjœck›Z^€bdš‰‘Õqd¢GS{6@]0GiA`‚P^zALe@f‹dužkx¢^]‡UnŒlvŠ[€—`x“Tn¦^s­^~¤Re}O|Ut“TRa@lxjy»”ŸÈ‘½˜Çx–¤dx‹Lp^Š®tš³j²dt‡j‘¢~›t†º—½Ž¯ji”cYŽu–ÊŠ¹…¶}†¸wyª„ˆž`—’o˜›nSm;NW";V>IdPPp[p–x†¬g~¢[Yry™`_ƒaemy«nq–mqY_mJPmVc’o‚™hj€\]tHU]:Q_8=Y6;E/NAAY$HM0[Y*^b2\f6Rk@abANoBZaLgT6cW?AZDPDIWM.T]2S`KgW$Br/.O1+""51;@UF)gS,m|=BoE=IJVF+FnB9TA==&;G$F8!œ\4ÿÈMÿÿ°ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿæÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ•çÝx„a›”kq‰hQh”R[‹h³†F\•[ohC‹l7q_PˆYc`=cT>½ŒUTltV?GmO;Q]vGYAZ|>ƒt1Ÿ‹^Ã|TM{Sop1rI_¬hu5©9tÜ”~KHg0Wh1cx7¨FqÂucoDW\H‡oE˜Ç¶îŒvÉq™bE§VŸ~`c0Œ8•Ä[µÈp“䈲±w”Òy‹ŒjŽ´_—:v„p}™C…c—¦i@¹]-D”N/Êÿº­\Lx'‹HÖ¨vÎÜ‚Ôÿ«ÎvpsCñ—ŸŠÃk£LŠF­ÉWš­h]‡Ckr7{h9™­k—Ÿ`ºÐ€ƒShg±FŒ€RLj'Hk(qiCˆyhŒ„k¤À“’hp}…W?_g„6އ`¡‘hÄÿ£¹s¨®jËŽrk];š–jvHžŒi¹šo³«aÁž{…MÜÒŸs`‚_H’jLª sÅí‘ÿÿÿÿñ·ÿÿ±Ôõ“ÓÂ…—“h©ÒyjŽEgCeySQDCa4;S5KC%MQJX3WB7eM,gc8ReHJTIdL4W1´{EÔ|_ô‰dÿ™oÿ ÿ…‚ÿÅÿñÑÿÿæÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿW–éEE”N89pD6x{KŠb§ŽVI¬n)\<1$ZD7\?iL5^€/ldcfS/ld:P‘;,tG320N=Na1VdK,KY)O^.P?] QÄu?Œt‹ÛX_°\>w9CM'eM%y~H{jKj–]YiA™Y=Y—P¥w6rˆXXpGdbC†;sU†“ef˜spo;nm-8ŸWVA!TY5ÀO,¡ÿ±f˜}Ê\GLˆ†ˆh.‰pQJ‚Rd](¬g;ÿ¾{hÌšOYE^^1‰eF{^;ß crÆ£]§Z£ØQ¾îƒƒŠ†i[Jnt7†”T„ƒbs¡QMŒ:…q5d~D–GjŸaƒp@ЧV*08R Vm/rx—Ìe€¼a™K;‡¦tŒ6,\kBÔ~r•”^l³^•{OÁ¿|±½w„˜b­¦gì°•±§o¨²±¸³ê«qa5П“‚¾Tbj;Ra7=H"BJ)yu:12BAc/AMˆƒ\©¸‚ŽÇjl¢Fzn@~qLÑ£…fo>²{bË‹y¦‡bºeshCš‰X‘pZ¸²}xXAK¨»t¼µ‰Ð£¤¬ÉˆŸ¶ÿÿÿÿС¤Ý|­â’š§ƒ¼ü¬£Ô‰~Àdn£Z¤À~ÕÚ¥ƒ•N]j2^\7}˜Eq¢4HD*v{Z^}:>D)lZ;_V4RT-jQF`“M·Â›øÿºŠÕTTo7Vt0Cf'LW0kxk¿ø¥‘Édp–C¬À|e¤C}C{©Kn‰Boš\Q8Ox-@I3j˜äÿ¯¶ã¥µè“³Â~’©_k£e…¸rŒ²|’¶¡¿áŽ{Ÿ~¢Ò€ŒØqá{n¬i”¨szªMo•LbI:K#9H0[’`q¬duŸhœÑ—ÿÿÒÿÿÌüÿÇäÿ ¼ÿÐÿ¸î•Ñÿ¨·æ›Çð¨®Ä€~ `]uC|‹IcLiwNkŽn›ºz‡±UšL`‹Xx¦cn™YnŽl‡·Š¡Ù†•³]^q4?d28d5IeO‰~_‡ª}’­jŠ«Tj†@n•WušXm‡6Sv6Y@`‡>aEbSb›bc^v–hz•F[wUb„[gŒ^g[x™s–Åz’±v‘µ}”µ}€œYSz;K‰[p²^wi…¯es—Rw‘CWk2Gk,E`?GkLWtGVpLib5+19FVFZnQVv~¢®w{—^pŽ[e{TWyQ^_ibcWa}_glR[pHMk@Sa<^_4Qi2>NA:N3\X²ˆk|<—€>ê~DP‡Okj6~‹ON„Q†s;i±^\„IXvJµ…@p}]m‹F%D7.[&\4h•Vb“Sc_5sŠFRJi\8S€=M`6‘j5fNIlˆ:…‘?­¡r§šx‹Â¡f†>²™`ÿ×}Vµw|s3Zªdys5„NZq;„E‘ƒIz°€i‘:lˆ^n¬am‚PÿË|ˆŠ~qš\Ž?Ãæ|¦÷½ŸÊ—U€CeLŠ—SÃÁ‰ïïÅãÿ·½ü•¼Îƒ´å‰³ö›ˆÓt©Ý‡¾ÿ“èœËÐ{cçx“tQfÀTZ—Çn‰›cœ|]‡Nf[;ja4u“jµzV¯‡b² kÐóªzÿ•äÉw~{L¡vH›¶d£Áz’±VÓß“xsC÷¤‰rz=‚•Z¢ƒaxxJšfXum@Sg5›‹vÉv™‡P\V5Ra7E^1bxMcgLBa/ˆjUBW#fW3[K–¬€¤Ô‡®¦lz]UM5•Z{nY¢žgÿ£ðÿɼü¯Íˆ¸ïx›`„fd˜»‡‡´p±Üœ¥Ñ‹E4iUCeS@ia8cf:bA´·„˜Ó{›ßkkŸR¿d…¼_©j¤ÏœÅ÷°ñÿЦç~¢œq°¶t…£\`}?“m’ši~Š`¤Ãq˜ÔeŒœ^bzA€™T Xt·klŽ][M„±p‡Í€¡¥v›´}½è‰t˜Vt–Qz‡]u›F\ŽKg‘xÂΦÀ}’·Ñœ¬Öy‡“n„¥q¢¼ƒµÙŒ·æ¥¶é~ˆÍYl¿[t³z‹Æ„}Çyªì·ÿÿäÿÿÿÿÿéÿÿÂáÿ²ÑÿÆö¡Á×— º¢q‡q¡žgy«Lbœ8^:JqAg‡c†mf~FZ~PfŽ_ƒŸNOiTM4uU1…ƒ9‹’WMk*cSD;/^MŽm-¬‰B­ŸmÄŸvæoÿˆeÿ¢fÿ©{ÿ©þ  ÿ•‘ÿ¦¬Á›€Œ¢‡qxöaeÿaÿ÷¸ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿäúÿ_•Ü)F{"#1  9_9fb7bgPQuJtgAfr5OŠTUfD^=§>Qºy6r{KB2ud%s6¯€J“°ffâKg^TZKig5u‰F{€AI“S~RP[ŸA¨™`ÿìkÿÿ°ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÞÿÿÿ¶ÿÿÿÿÿüÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¶êÿ}}£všm”U‘¬gœhª²hQ§ou‰d—jcsGzŽ?[zFCn:NZ+qa2¾reQDª–HxÑ~ieBxD­œnn‡Ppk@E(fP:vmLnlVf‚S¤ŒaÆý©§ÿœ”ËoÇñ£úÿÚëÿÁ»öšËÎìÿ»­¢^®·n¢·]”‹V…uFi[AvˆNh†KMI~YÿÜë¬È…‰¹iþ߀²Õm½Õ|”±y©ì™œ¹‹Œ¿lYK+bS0ZO6-.LK/„ŸY…“]g{;`^<|ˆT\nR~ABX5\nXq“kt§bs§Qb:Lmjfeµ¹i„ Z_9OjGhˆmŒÅo‹Èb|¶HAoAcŽt ÂƒŸ»|›¹bv”IbsHQeNs]bsRjhp•bg†ADc+ISPH3Me2hf?‚n?²‚Yå¥}ô”ÿ’„ïŸwÉ£Žò†‰ÿÿ¦Šÿ©ÿÄ­Ë­‘‡žÐnzÿŒ~ÿϨÿýåÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ×ÁïP|©+Al$&6&'  7 H7EO2RJ3MY5PbA‚]6ƒ3s£`“u]‡šRdª‚Ch_XJa`+gX‡œag~\rzA‹mPІQb”t{n]P__hA¾ˆ-pñ`wDX7‡¡JR€bIK3Qq,[o4h…9Ø„KZÿÄSI>«Š@ÔØ“Ää¼ÒÔºÅû½–ï„­uNgQeW*T{JrR8šŽFWƒ‚qJ5ë¦KzƼq`;bZ9ms@Rt>jh'Lt9tV'L‰Y\j6Ty5lƒ=:hHcP#]x@žf>›j~¸‰[«Uw…CŒ†]{£v cP‘ez¯dkÆbe¾Yc~:euFÿ˜Oy‘h‚—MuqJ{–XpW_‡FPzNYk)^W/Z?2|‡R`q:‡rAÊt‹‰P‡~H}_oN}‹Pæ‡7±Û‚¤ RœÏY–?‡•Iž£YMBNy>a](€“XÓ’Mq—<Ÿ¡V„˜T°­bv•x£›I‹ÀXn5dF4Ÿo±³„·ÚÆß¯£ÞŒ¦ÿ·¾ZËܮݨ§¨k^Hž‘_´ê±ÿªÕÅ{Ïý¼Šó®“¼…žÊ‰Xb+sžYëÈ|Õ×£ƒcqG›ŒNЭ€»ÿçâ™ÿû£ªfMv+™I’È_ª¥kdˆJ~pÿ•pYk3‰vLŒ}L‚q;Ï…Y²Tv—Lc€JqzCqqD‹£`z¯oNq9Fp56\39Q=B]KC\Sh„tŠ»ž»wŒ±nw¡MNl#1A!-A*?I3Nb6[f7WS0NJ0Of4Cf7FZ9KR9>_yª…ž©b}˜}’Å}—º\gDa‡Gf™A]TpGo‰_”ŠA–°Yo£ƒçz]ÿígÿÿºÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¡ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿýÿô‡ÿÿÇÿÿáÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿüÿÿÿ¢Ïÿï”ÿðÏyŸ°>orc`,¢Š9˳]tØŸŒ{b™­`ʈŒºibd\uFKO@pt3acT|GŸž`vœu~`H]{OfrC|v>|ˆG9’t—d5ÁuVžVf=_wDLŒH;Z9ÈV$Z˜[[xBjd9]„W;h6AW6aT Ž`>a­`q…;w”N¥£`{¡vKjO8_0KA'fu/kk2eb2vhd‚A‰Qf­U¬](‡—_M~Bkq?¢EM|7Ot1nƒ9Ãs>}›d°‘=•œvÔ¤ƒeªz”³s­“W¨[hŽERO3:E%}jCÁ¦ ‡Ý¬ÿÁ¤ÿÿÿ±üÏϳe§ïÁ^¢]k¤c‘¥WÈÕ‰»òœÄꛯӯâ»È֕ײ]ßÿÞˆ…Lv{Lj^3‰„=}L‰šfÓjGÉ ’ŸÄp¡°luQ2yŒF¬¬išVfV-~`J¾skÁnKy7Ij+\d7‡ŸcŠŽ`¼­i~¦cn}BžhÓÓpFpg9b•Kl\[y@Jb)Sh,8t,‰žiFa*L^@~ˆWW‰Gf‰`‹®o‹¼‹‰Ä‚€µq†{À†ŒÁƒ…½z€©†¬µƒw­X\tLºŒ¯Ôš}±Vl–rm–[XXPr1:L9e‰=K[@w‹j”Y~aužNh•MLs=VsiÑà©àq­Õz½ð¥ÿÿÍþÿœqšHHy9r–rž¹[®_ Á\†¡d~±RUˆFh¢i•¶|{˜Kvk‰ºrn£ICh8QmR†ªW\™8Di2RdGs…_jŒRc…I:`-/G.3N/B\vº§‹©´Œ˜·kq“a‚žViš_j¸e|£B[€>YuDa|IqŠ\q‡MZ]Abkf‚›v~¦pyµrrªa`—Xe’PMr:C]7UnCSn<:n65]<9c5AeRk–t¦Š—̘žÎy 9>\)?N&5=5NiDRe8PW2JMDnG^‡HSqGXlLYuSUbD?J0=QUo•|»oz¡\z£at°Td`BbhA]b?[_2fP9Z>{„HW|des[gnMfsH{qGƒ€M£ŒP´`pª‚„œƒ\Ø–dþ’kÿ†ÿ´ƒÿ¸ÿ»žÿÅ›ÿ¾¥ÿÇ‘ÿÓ–ßÄš¦‘ÆpoÚxbסÿ—¦ÿ¨¤ÿÿãÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ\£Ø!9›D '$+)$*&.$*0-+..2<E;SO&YU2KX>JaE~W4‚€@}˜]gŒqea[aqCeaFvJ4|N3Œ{;‚‹R‚ƒLŠ S¨]š¾ÿÏ“ÿÿ”ÿÿöÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¬ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿø¶ÿÿÕÿÿðçÿôÿÃvÿÿÔÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÙçÿÿÇÇÿÿÅŽ–Øbiƒ:_G_Z$žz1¯¹O¤³yšv’~gŸZi›uZqIMrJo^4‹}Nn°lo€gsŒVœnRzs\¤ŠUxvˆo«UNƒU“H=€—L\–‰^oLQ[=`\-aN7g‡AQ‚I‚‹9U¦QYj=_h._oF€‘:w¥\s˜Y¾¢c‰é‹|Ü„{Îts¶eg~RBr1AV'UQ,Yf6Ui3La8lU-ži=undF¢­Q Éšr¦‚‚}[]Œj]¡HbkAKmBX—:mW9v¡]B™fg@$°èmlbr‡M7VNK‰s>swHÂIJŒxX6ê†9ÏÉ‚ƒ¼œƒ±Z|Ûv|µlox8s“L£’[„¡jcs‰[†¬X¢Åfˆ²€œ€X¾×¥Ãî“ÞýÄÂ乽ޯƟ‡Á‹hrE‡=@e%9\#>Cj\#?U/r?'O“Z_t?hQ+¢v\r­gŒšIª–Zl­ru‡RBB*iÈ]l‘(‘¶K}bBk¬s¸zNØŒc`vJlj-n‚K‰”O¡o$懲~c¯hU‹o[¥–‚†‘ƒ¤­Ž‘Ÿk}ªqQµ`DT%pJ-‚‰cíšdÿÿüéÿÊ ÿÀ…®]‰ªXgz?{€F©¤¥ª®ŸÑ¼~’SÆì³{žYñé“qçiƒ™R¾…`³ªtÒšq‘–LZˆKY£>u`BŠP)dk3eb0©yc“ebV, yTv“SKg1hb0•qNj‡C…ŸQ¿ÿ¶¬[¯—`ŒÂsÿÌëe:Sj1¤^qc:”g]‘L(%&*X_?SD)V´:Š„D†«I†eIyU5…}UŽ~Uuei±_WˆAZv;ކUXg2Xx2Á¥[d¢9[a(PK0‰~[·z}µ ‡‚gH×m²ß„•Ûpäñ˜¸ÿ’«ç€À¾…ÿÿçˆTŠ“_…ŽOƒ„ki¬N9‚'k32£_™žeŒÃ`„€JyCcP9¥{Øï¿¨Ê€y˜Qˆ°gŠËed—Bj‘D`‹9Y~;|™jÍÿÔÂïŒT7suIZj*X„3x™V\‰>Jc2eŠL\xHbˆHdŒ@czQ{œwˆ«{®zjÁd“®ˆ‘Äuªl~¦go™_b8FX5j€z|ORbKl‹eo†a^ˆQ\J\mF_…4HX0KP2kbIu‚W„†Wvœ[k›y}®‰”Ç{‹¤P~Ÿ[вs¯Ë’×Þ¡ÑÕ“£Æ_h‡g‹®r”ǃœÄn•»Š£Ú‚|Âts¸ng¤ciŠIcgƒžeo…Lp†Na†Ss h›Óq{±ac˜LZZp‘argn Wh…QKo=4UFcyj†¯‰«iq›i•¸±á£Ý䉞½NR1I{1H{8NE@S0L\?\ƒf~²y‘©{‹ºˆŠµwz©uv _f”JQt5;\CV‰]o¤Xi¥eg¢OV€Ia‰Yk€‡œ¹šžÌ–˜Èoo¥G]Y(C]@a€SoC\jDmvPqŠXt‰]n„ms¨yŠ´N]o39T11YPW)Nb.@6#o>&ušh_t@b‹=…rG‘³\p©W˜|Mj¨q¨¡W~¡hu‡5‚©n„j7˜„N‡Nbja1tLMé~tÜô‰ÿÿ¹zÕ~Z¯b2Q.”nKŒ±l¯ÂwxÃ{×®x¶½n¨¡€Õ׊çÿ½ÕÿÒ¡˜l¢·s¶¤f°’eÖ¬k²ò q”Nj­7¬5ãÿsoÿ[`—P„VDW>!h6$zM”‰Vr„c¥A;iOI10g9N?%("& $ 6$a72T(G9/7V$F/-**?!4!.&UC†m Œ™Dgi|{fo€CZ’sCpJMK3YU*rR4nY2y{EžmC¯ŒOÿ¯nÿþÿÿêÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿéÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿæÿÿñÎÒÜͽ†ÿÜoÿÿÜÑÿÿÿ±]ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿªÝÿ­o¯•‰b;ftA42`C1623RM.I\+eR'cPH–oKŠ»^ˆ§qi˜seqWsoAŠsM¤Œ_‹¨_y“qmŠdDjSuE4_dD\rC—ˆS_Žj‘^>xxFu}Mwl< ƒJ”wf|W–‘7“•]‚„[>uJ6I&š@E†_N]'A‡Iw6(]5`;¨•Xd§i\j6†ŽAsh™t>–¶x­tY‚MiG—QP¬uP|=Xl9U}D³r1a„tf>Y€@‚h>ÿƒP…ÿÛƒ–ZFŠY<]$aa"œ¶k©Ø ŸÛ£|¬ƒ½ÜšÈâÄÃ뤟ñ²±È†²xˆšaª©o«½’tyh±||ØqŒå°ßóíêðÿÿtÿßT´Q}ƒ*N±hW®]`‰A–—Ov«}€²p\”XšÇmc\tf1d|c|iEto=d~u§U¶ŽoLp¬C$Ÿp½“x’™i»z³k¹µ‚•د{¾v‚¥gz¢p€•kºÅ`Ÿÿ¥{Ä–:T0l¼}ª¼›¤ž†È ŽiP ŒnÓˆ”¾ßÿŬ뇱g˜PÿµvËùž›z›‡T‹„Fÿÿ‘ÿÿÿÿÿÿÿÿÜèÿ›ßÔ¦W”w9`u1]g/€‰r`}Ep{FŸ‹XeGÖ¬w‘Е €[ȹj‹…W_òĘX»j‡­WŽŠXj‹M”…Wþÿ²Ž¶zޏr§Ñ}sM3fW4…‚]±ÕŠÄÒ«Yf7lxD\šU{9Gm8RnGexYjŒ\T‹N\QU‡DMs:Yr=Rt9IzPv¡i~Ábw­}ºë‹•Ïp‚¦IWi8PxBD]Aymw©Ã}·jx§y¿œ›Á{o—P[u@b…Stœ[mYz©io›}¡ãÉÍìºÉñŸ±Ö‡Šµz~®[ew6?S"3M0OpDRg\h”nv‘NPg'1J(8U>Nj_p”ijw67@)<[KQ‡ˆÄ›—Ï¡—¸ˆ‘»o~šWm_ˆ—dm†WjrHetTnbnˆe}u“ kubx¢]ZrQo„M`…Tg}KXlDUz_OVKzZ9lf7q[GacPVcBPV>Hb1[T8S`5T[:_X6gZ9‹V=zaAlXHs\F}_B³pN°SÉŸuä“yô’oï£zÿŸÿ™|ÿ°ÿÈÿä©ÿâ®ÿá¯ÿÖ±ÿЯµ„”uc—]Rý[Jÿi\ÿ«¡‹›ÔLS¢8:`F71`U1shAk…WJc5u`)E>*$ #&("F%V:4J.XI4Gg.@l:JS,3]+%@/<%kH—p%‹¶bw£leˆbtqOY…[[hPwhAZ€?Ua@h`7yz@ùœPÿîxÿÿ¹ÿÿöÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿåÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿé£ÿÿüÿÿÿÿÿüÿÿÿÿÿÿÿÿÎÞáç¼ï¿®à¹ÄƇÿätÿÿ®ÿÿÿÿÿÿÿÿžÿÿÿÿÿÿÿÿÿTjìzMSIY5S.Qd^0qb46:Fd<)ul8oa6LiBhK,©|3e¦e7E^^/-gg6žl9s ˜gŠ^oƒK[‹MT\FMU@wc,X}ZrNM€WHgEBC,T_*8YDSBi[3of5a‚Ot‰9ªŽKk›nFv=?].MY$e0ZƒCƒs5·bHi^Wg3š†6F€XXS&|\1O‚KIu>W\3j;VhHgs5tŽILkMn?9šoJž¥wÉnŸt™—\S¨“S_<„n;1a=B!fZ-Y€SŽCwRV…j…™ES”XHp7K^,cn/›„9MÍIR.Œ@%”…e™¯]½ÀuŠ·€k¥Wk¡MªZ=ÿ·ns·žKoJCc$L|2 ^$ªÅ•Üê­ž­²ˆ­›ðèŠÕ½§£Eº×‘wî¨X|GYb6PtG“c5k°šfS>IN5©‰I¡Á‹·®u›­‹o­sŽ™P_¨c\iD_~K´wG‡Ã ]n×wq~:[o:ct6~JL|J…{4_xPxyA’´ŠT¬ThR*}vCª¡_«l™—mÑzLùreÀ°¡©Š¦{xˆvsqUP<¤Ç€­xž’ovVTZ,ŠwKƒŒMu§Z•ì‘tŽB`ÃTkk=]{>PY)ˆ iÍÎxÐû–¶ÝmÒÑm޵j¸¢ZŧW·¯p›ˆHššVÿ¢]ÿüãÿÿÎÿÿÚÈhZi]?Vi4ÒLGÿ”•†PVk7¯dp}J…©go­Xª³ˆ™¦p–’PƤyQÎʶ¸šg÷ƒj‹•d‘cHÿä˯™vÉ |dd9fb:›p±§mmxBgwDmA‡®fâɸ–¢h³À‘Ù|@M!VH*y`@v•PktF;D!XZ*MN*VO)iT3vq=†…I–Ódëñ¹ÿÿßùÿÚÆþžäû¸Íò—”¹v\•Rš¡g¥µwÂö¨¸þ“¶ç ¢ÐŠ¾Â œµhz¹Rk†=K[:shH†­h—Ëy¡±w°²xz’PtX|œeU`8OK#V_3V[?sP©¬f¦´sxªHež?l§8Ki,^–G‰Ægz­^šÆr;9?:)DP+:L$Q[AWzB;],M^AKsL_…JWzH`€W“³’Š“YfœR‚šN^q=Vh-ET/@i@[‚E\„^SŠHr–Xx‘WVo@oUx€IWw;nyz€¸„¶coRm“h_¤Xrž{¥Úƒo±Ze›VrµPjžKZ•GU„KIMh„_š±yʆŒÂ…š¿r~¦VaŒ[v¯q„´t‡Çv‚§f‰¥l´Ã¢´÷mLc)5-^4‘\#yžYskVŽdfeMeu<_jNgI„rEz|XÀ‡ZÿÖlÿÿµÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÞÿÿµÂÿï©ÿÿÑÿÿæÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿåÿÿÿí¨ÿø†ÿÿÿÿÿÿÿÿÿŠÿÿn~ÿ†Gÿÿ{ÿÿóêè´ÿïÿÿÚÿÿÿÿÿÿÿÿ˜ÿÿÿ`ž?ZqJP/gb-=ŠG^B2Šc.jT1¥jC—¢d•’Ux’eorWNY1€g+UˆD^^-R{4WZBÿ^2²ÿöf‘‡r‚nzGNuSEp7OJ'^i2x†DkkUe}U`jXMtDRZ:ZlC]gC[{G`z;~pDz‰_ÁÚth¿–S›K>2Nf%dj(t¤P‚˜Vt¬{pAyC’\¥Ò‹·Þ““á­l‘j¨‘L¥×T¥hEd)?V!Rf!k`%m‡Dr>x€Zj˜q¦„8¨wıužì¶ˆ•cU|QFR/E\/m~‡Ç€Í††QªTVe,a‰J“pWe¢\}‡EiÆ]SZ.¾vN”™bDzs»”}™kÿ¶¸¸ g”kLÜŽˆ_w¤g²£gÊÍ›vÌ`7Y"€YB“³m”…S¶itƒL\H4»ÇŸdC0«±o’uRl–M’dIµŒgɳ{‡QŽNÏ^°duTŠœUšUÜÇ’’Âb‡–iÿôÄÒí²¼Ñ‘ÏÜ—¨¡l·Œ`†U«k]„ Q¥§‚›¦b³¥£_–žsÛ⨵±x³Œ~ÆÔŒŠ•Weš[®±|‹¥kŒ¶tj½QG_2Yr7SwA}š\P›5?m/w¤_“Æl~Î]v›[k‹F\|0[~;j•Sœ×r­òrpšEŠ”xÅã›{·EKq;E\7VcbxŒ^XPŸÔnž½be˜X‹ÎjlŸx‹°lt®it§gv²`d¨\bŽFOeEa|\n”_|°v…£s‰¥a—£jx”Iis[rh¹‚Ž¿‰Á‰‰µsz¤Mh{;PdIhzZf–[p™Sm•eƒ¡Xf~JOjEP^29Q$5R9CbH_ˆa™³Sbm0=R3Fj[h–„~¥nk“``}EeqFWnBSyKNrI_€RZ}LlpR}ŒNmWHšeKfL^e2qˆA{”\r›kZjim[e{LlpYtgLokHlcKshByƒIŽZÉ—c”™liƒs•RYÒY.î‡RõŽuÿšsÿšÿ´‡ÿ¹“ÿñ¢ÿÿËÿÿÔÿÒÌÿ¹”ÿ­œÿ·“ÿãøª’ÿ}þ›sÿš}ÿnÿŠn¸¤t»š|͵lÇÓ‹Ö°h®žApKYFVa.ng6pg6S`>vc>v=j‰Zg€L5zECH4?e$2d/J7,`;l^+zLS§[fiVn~;dyPhvX›wIÿ°Tÿÿ•ÿÿæÿÿÿÿÿÿÿÿÿÿüøÿÿýÿÿÿÿÿÿÿÿÿÿèÚÿâ€ÿâ‚ÿê•ÿÿ­ÿÿÿÿÿ÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿúÕ¾ìËÇÿà–ÿÝÿÿÍÿÿ¼ÿÿÿîÿÿ…ÊÌ«’]ÿÉKÿÙƒÿÿËÏá½àͨÿ›cÿÿŽÿÿÿøÒÿWy™bcJztATšV¬w:f´jqcKo‚G³e8ɧ]œœ~®»{€®:y\[K%kv.Ry:WZ/r^6~™QÿbHÿ…cŒ—_t1’†Sa½bˆQjžZy„fY}°ëšt«qt SqƒSd†YVuIH‰:RS"T„HxD/UyGDL+ST'`y4ކ=̉ixE:c7[]-uq@nK—bRæ–[AaK›}L€`Ø…uÁ·qÿÖŽÿÿÏÿÿßÿÿîñÿ½Ÿ¤`GŒUK©—yÄS»¿}§×ŠžÂ›–´Šƒ³{T¨b—¢T€ÔenK¸¯|ÞrtFj•VmŒNŸªUòÙ¤ÝoÒcak9jk1|œ`˜‹Shl=‡‘BvœD£¡\«½u®€UÞŸu…}MÇ’p˜pQƒŒJ•bm˜Zˆ’T¥_K¬V—Ñrot@mF5–Ršwcλ„‚ăjn@¸„z~’S}l@ÿ­…çÛl™S¤nR¦­zÏy^‡Ag½KwO‰«dÀ©…¾­p“ h{¿ai•<žÂ‰œÊužže©}c¶až–W´¢mryH³¼Š˜´j às¡Îjx“IÞý–Àÿ”‹±lв’vŸhÃø¼Æí³ªØ—ÁË«´k¡iTš³W©r\„SƒW²qŸ‡géwpÖ€cÎwo½zj¿°s‘iJ{c?a‡A|ˆ]š³u¤np›I\ˆQŒ‰UŒÁf†¾}Ïl‡¹|‡ÕnžµsÇi|¸V~¯Uxª\†žn†ÃfP‘<ƒc‹žO”·w½TV‰@Lf@WbI`uQiaH]V5HZD–°wÇ|•ªv•½{t“^‰³„‚±xm‰R|…TIu8d~h¼²z€\} \h—a~¡bŸOo¶fŠÀcެ¢Ì{ŽžPci8\}Qkna…™t’µk{±r­£Ðxˆ²t·Û‹¥Ö~£Égk‡Tsžq’Һ߮®ávtªPl—JlŽAOtFc„_‰°ƒ†¿‚—º’¿ìÒÿÿ£ž½Q]CWaY€›{‡›os}NFT.kB`‹ev¹nsªu™Äš»à‹ŒÐ¡µéŸªë›Ì挥¸r›jšWx—i}«tw´€}¹xs“IO_]l‹{x ‡¨}„”oq˜]v‰GSwGLmScxQkŽFd…;N_/@d=M{KINP‹SU‹IM~LaYnv2GM'?V2@a[\“|y¨w~œgs‹]–^s…Wi‡X^‚P^uEUoBpkO„ˆU^—gB†ddYTzt2x”Zm‚fŒ€W†h^vU`|No~O|P~ƒG‚rQzTt™c†dŸ{T‰x[kwz€RU¬P1µnBÔt_ç‡gÿ•nÿ sÿ¹ÿÔ—ÿï´ÿÕÈÿ·³ÿ¶˜ÿ¸¨ÿ´¢ÿ˰ÿÑÄÿ¿ŸÿŪõ±¨ø”Œÿ‡|ÿ‚pÿ”xú·Šò×’¤ßµ}´°[‰tXmWVbDbR7‰dpkPkvšhˆ f±‡WK…fSI/Vm5íc:›Í”mŠd?bI7=)1399OF Vo:oq7W‹P{tCTuca}>XrSCyIKl4]j.jqA­¢]œ·–‹Ý‘j†^i•C~”:h§`¼[Ê€\¡ÿ´o—iJºU@n&“f}Á{QfNwŽ4Š«RsÝlS‰G~~I™¡U|ÎyªŸ\^ç­„‡AK–YH]$ci1~ÈxIZ]z-%G*-:QV#š•OƒÁ†{؃‡‰GnµT„–Kž»lq¯_£šShÁ_ƒBNy=CL1@@yx?Xz[Qs9=[(OZ$iŠKj|Dœš]“­co’OZ…Nt‘Q}‚HŠcfi:^u;Ka/fCv„Z²kâĈÿÔŒÿÿÅòÿºÓÿ oŠnoB‰¤gpk\¯g]¡¾ƒÓ´‚GM¿Ð³õ®±Û h²|Å“X¤ÿ¿R²^o™U]I{…Eg~;–¥T¹Ú²‰]·UZ„AH\,cj9Pa4•fL–VŒ¢s¨¡eÒË ¥±s‡´cv®M–£a—‰Ww|HtŠD{~Hy—EÝ¡‰§±lÐÐwž[œzY§Äp…wN˜‚iš‹p~šfŽjKœpSi}Cy™NzJû¦ƒ|‡[YI1º|`Øþ¶£”mŒeUµ{cˆœmœv^¯ˆoॗòÙ•ž´}¾Å¨ Ê…¯…V´™a“K£ªdáÉžÃlp·]‘œR£›klY:ŒySǼ€ÙÞ“×òšk R|‹c’¤kâá²›©{wˆOž˜`†œOjG–hL¬–iºèŒîÄ•¡¦j~†J”uMãªpÿ§v›ŠRZc0ez5NN)dƒQ‰|b²c¥¹{ŒÇn¦è‚È߃¨¯‚¢¦xªâ™§Å‚ÂÞ’†¾`‰°by¯hp‘fužn›™NW~8t–Xh–O˜¸z Z‹ŽN_‡M\€GirC{yIyz?YzV‹³u“Å~‘Ãzy ^|“l…˜__nJmfOxVfŠIn…_ª³m…§Vp™Sl›Vf…Nn|[rQ∕±hqX»[\ƒ=UyFV|Pg¡t„Îp¯Ü’­æ‡ˆÆiv¢n’¸rŒ­f{¡a~‚e‡¥•¨Ò¤«½mzŠNi”Kx¥F\†O^uHmutŽ·fw©lŒ£ôÿ»ŽÄTn’\u±]ošk|œ[dp@QwBN‡[o¯tÄ‚Ïxz­yˆ¹Œ²Õ¬Ï£¨µ~³·z²v¨„¢ÈyŒ¨c¨wƒ½Ä„޾†¯de˜cq’qz§qŽºcušYeyH_sK`|?XeOY“tÕmbŠ+:Y8R}`l—k{‹iª©Ì}ƒ±f{¡Tau.24'=I;N|ax›qu—ik‘_p„cv–f|dn‚Xd|O_{LX}Gnd<]}RA‚YI]NbH0tn6i†[\Žq_ylmsLn‹JnƒW`ƒZewX}d@xm»€]Ì‚Yêlÿ–gÿ¤yÿË‘ÿÓ¨ô¿ªÿªÿ±”ÿ¹ ÿ­¡ÿ­œÿƶÿ²ÿÕ©ÿßÉﺯɤ–é…|ÿ„tÿ‘y÷´ˆŸÇœVŸ¢XgkXU;Di:L\6{i7UyC\YC]f-^SA|[3|E‰¢aŒ¢^w¥fVgT\LXV:fL.Yn3™g=صQÿðœÿÿ·ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿöÿÿïÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿîÿÿݸÿÿ­ÿÿó®ìγ׎ÿÁhÿÃ…ÿâÿÿðÓïÿÿÄx÷»vѱ›«ª†ÿ›Yàÿƒ…­´o’O… Y¥¬U`ŸTu|cNŸLOkI‚R.aˆHpmKnyLgzOw|;s—YƒSUˆpadEwrCb‹Ytl2hƒXŸS’F„‰E¬x@gŸz¤:Ïm˜qh¤p^V‚SR‘]Žr?jzeyxRb€@`\<{pEnO‡‡KW}VEz:WT1ei4M[BFd0Nd,dq4oŠDtNµh‹±a£ºn³Äz¬˜²fƒ–zpuRgcJyV6T3/4 LI^d0mh:X†VRyI]c?MƒKJk5Cd7xn.©µSt€YI—\e…8…¥S¡ndžqƒ‹Bd—aq‘L•~Il—ië¯Y¶ J§c^d~ŸBP¥pv|9}šNœ§UÎÀq¼ÓõÑʡؼ²Â‘}Ô©k‚R[…DCq7xr%F¿hh‹/3x@(D0CCS sv5‚˜V{LŒÁbf™]|–D¡Ë^zÓ~ÍœT[¤…Hes;qJO_:[q4~`1S‚;Hq/c~A‰q8mHˆhv®_‚ Qn†Nƒ¨ul«NTŒ7vŒ>r–]ŒœfÁiÅ™\ÿµ†öõžÿÿÛüßÂòꭡؤ¨›gªÈ©reA‹}V¶·pL©gŠN-±ŸšÉ‹ŸWk/—˜F›­`°dV’LCK#åTV¾ÿ¦¤Òy”Da5‡¡MHd,^P%IW6g;-w¢sŽ™aIW'iQ5£…]¥oEÓׇéÿÌ«ü²×®m ŠOyŠI{‘H‚G«Á‰ŒV–ck•E²¸m’zT¸ˆx‘gYŒÅš€gH¶`sŠH·fÿÿÒÔÞ“ôÿ»•Ýey£K²ŠqæÿÇÄЋ‰ÉToƒG• nÄÆ„¯Ï‘³¥xœÜq~Ñhˆ¶^†¢Q—€aá—wz„U„«ipŠQw´^¶Õ“€Ñ\}¾gR‰5Br&9o"dY8‘j—Ë€y›N’’f‰¬ezSjm@—] ä„µê‰Åì£Çw°Ìƒ±œn¨ºh Vž¢]ªu™•b¬¥j“Çg¥’`t¦IT_/FS'frP¥à}©â„±Ôz¡Ôu—¾uŠén†Õf©Éž©Ìt…§m«Èq‡ªd˜¥ƒƒÂ‚¿žU[“;Z–Ki¡Pi«M‰³t°ºŠ£ªu·–pn€Nv‚\sŸ_qŸKb€G„œj˜µƒ‹¦]€{Q‘®]}¢nÿå ¥¡V”ƒKsƒDk„M}tlÔ·tx¬Us›Td™QcQx¦sްzz¶„¡Ò’®Ð}Œ°YVˆN‘¹‘Ïã¥ÃÕ’®Û¡Èì §Ç„¯rv¤[RqBv¢Rdš]Œ¹“©ÈppF]–EjžVm To—^u—DPzcš½eimK~Ÿ~»Æ·ÒÿŒ›Ä¥¼myœ]–‚M_`€¼}‰¶¦Íˆ¡Ç—Ìw€·u‡°Š¶‚‹«c{ŽJa|M•†Y‡£pŒ¥`n‡Ph~ht¡x}ªˆ‚ÄŽ‰À~x›k_Œqv¡pÄm|°KWw0FaAUtRS‰€–п·î‰11F5D_Nbv@BT>Mga}”€›¶‡˜Ì‚Š”H6O/9WG]dQ[kUdxZh_jˆjj¡uw§kˆ†RUzQ^P_{^Hf-J_FH[;8Y3MB%dZ'`lETrVeqS€wCh˜P`ƒcEsX:YN^F2gMyT+€j6¤iR¢zQ†_n{c…cV¥l?µsI³`º|oµoàuaÿˆeÿ¤yÿÂ’Þ·£ÿ¢ˆÿ£…ÿ¿›ÿº«ÿ¶§ÿ´¡ÿµ¥ÿÅ¢ÿöÉÿêÐÿÖÂÿÈ´ú· ÿ”ÿ’t碃zšŒErnJE@gC,}y2\“XDbQB?/BJ%KJ1}N,wi5v‚TzŒRd›Og„YUkNOQ@r]7¢FÿÁcÿÿ›ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿüÿÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿôÿÿÖÿÿëÿÿàÿÿÿýɽ©Û¦ÏÜÿ˜iÝÒ§Š zþ‰o™O®…‚ÓP€sÿ‡Ud˜P†x~n¡CbrOWlI?fGFC'iK'lUW]HYa>dbG{lD ŽS…ŒYz¦f££jk¨j‹ŒyižONs_‚`2™P}”]f^axCs{5˜‰A¿¸h¦¤wk‡[iqRsu>‰O[ydEg:@a7Yi,px/œ@×ZxŽi€‡a^­rZ„FjL]eATF;Gl6Wh,Ya*tl0¶Î\j«gmQHqM§i4¾¡lœ¼}Ê¢s•—nUteDj=Dl7Gf4Wr0@X:¥`,W ttj<ˆd_‡hFnDy{4HpB™V-˜ˆ^¶Ô‡Ï¦a§z~“M€²bssHtd=tš\o£R[Q­ŽA^ì¨CT6Cc$„n$NƒSyr(f¬]v”;…žHŽ©fnU~ˆ_‚@›šIˆlYIiZVi2–ÈQÈoH¦X:`-9]'G^$t:nž`WŠB‹©En°c«M©´XÛà€{Ö“œ×pl–Y;e6Z`/g?wYDoBTV*P]0Nv.Ok/½_c¬cN›OVe,ˆq>u“<³no¥x|›\xd>Si9c1–—WÈꀠ׌§ä®¹_ž‘g§­y¤£ˆÒ¾”›vЯ€©o‰O§›aÓÁzsÎŽ6j+0;£h3*A$u0™¥mT”=\ŠG+Q"q:›cD~©r`t5¬EdpAqq:ss;T9%X;,qmR–gFOL)gqCVy†oM|ÇChbA|”QµaUaK¢ˆwhn8|“MoNÍÒ™”­tÀÚˆ¶Ç“Áæ²ÍÿÜÍÿÆÕÿͨÁ|»ÕèÙ³ßÿ¤¾ÆŠ´ð‹¤Àc¿¼{^œB]d<¶cq¾MvLƒÇXn—Oµ¨—´¾ˆÄµtŠ´}§­aŸY›–^ª”\’¬ ¥Âlu¡Rx¶xyœTt[}—q‹Ïl’“vo˜FWY7X]@icL}ˆp²µXj‹Cj‹R‚™lžj}‘Sr{[œ¯‰îþ™¶²hw QŠ‹U•d‰T†‰^|—TnId‰\w—w‡¶}½…†ºy‘°kŠ«x˜ gf†I_qRxtXš¹ƒ¶á¢¯ã~x™R_{Xp”GAW4bjI‚ `‰­]}“Z€¯^v¡WŒºw”Ä`u¢TqD]†]›ÅtdAn‰Ik††âû¡¤Âr~™UjŽ^Ø€}Ày~®n„•h…¯i‡ªal]r¬x‡´tš·zsŸ@Qh3UtE}zNz“\wQk…O[€\piq©…¸„‚«nh’adŒb]z[ui‚²KZu-JhQtšs„´ˆŠÄ™œ°tm>Ce-;VDOd86O.:V@Wwn‰©¢·Ðœ®Åu|žMSl?O`AUpB?_BQeZo•}’ÅŒÂ~…´wt¢^n•NedD+=A$EI$HK-OY5L_7b[Cys=c`SslE`R,M?CC/SC!fR,|N)¢a>­gM•yZ~€_“o]§sNÌxPÍŠ^º‘s¨¸}kØycÿ†dù‘o׮姓ÿ•‹ÿ¤‚ÿÕ¨ÿسÿÔÁÿ½·ÿ´¨ÿЭÿ×Ãÿͬÿæ¼ÿÚÂö¯±ÿ‡ÿ†wÿŠs·”u_€p€aIk„@Ld@QE8T'FP*Qd(^t?fu–…KZ´dŽkdÿŸQÿÿˆÿÿÐÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿõÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÝÿÿîÿÿÿÿÿÿÿÿÿÿÜÞÿ髳÷¬º¼… w~uFš„E]A_]1S^BH^3aa@P€LJF?1dX*iiBgvK’yS’•Sp“}RgS]a9\lCKbGId1Ca0`Y+‘}DC¶Œ@Y98R&FBW\*]o5z};e•]PeMc9U~a_|E[u3šv7Љqdˆ\}y?·¦rWÑ©M™Gnw,WtHVn4b‰6a…1m=fÂV`FV|>Xt2V‰1gh.w‡@l±\’ÌqZ£iPX(>c0AZ*du*“­QZ¦g|‹-{ÁWxIh¬aƒŒA›«U ©i¡Àz‚´fj¦`aŽHfŽGkœN>xIO`,V{/VŒ;½±J¢À~v«]?›YOg€¶q¢d…—dsŠN\€@_†d˜Ì‹®9>S.R|h¨È“³»YjŠL€›‰äȈªÖeq–FSY±^o¥Td˜Ql’md_wˆfˆ–PVJU~ByySrŸVZ‚Ux™]lœJ]mPrzaekqžbn©YWm>QhJSzVjŠO\€?NzLq’oƒ­x‹³ww¢cf˜LZe0?jxX8Ž–a3±EF(;e-wA"ŠœHTw]Fb4Z^,Oo:I^1O^&V‹1Rv9U4e–Rv…;‡šWÊœgZß­[qAQ{;WY/`pHY=jŠ4€Ž8x¬eu­aY‘L_…0Wp4”¨Jcš\}|>D—W^s-_‹DiJy©Qm‡Igž=Š·Dc„U‚¤SIdA©œ?Øø•€¶ng”GGS/†g*œlp^6ƒJ6a#Xbb‚4oGƒ¡f°P‡xFv¦JP=UW'RšJÌ•P»ÛŒâùŽÿÿÙÿÿìåÿßÿö”´ø™Úÿ½ÊÆ…ÈÖœ¼ÿ°¢è¨ÀÂÐÿŒƒ¹{i›^uT„{H–<¢†yŸr¶¸ksšlraGW•Phb+Kx;R‚BPp3se;ĆXdo>ƒ>e¶[\T%eN5¨žqÆÐŠ¢É|§§x‘‚Qâ¦vxhFÿ餮oWÿ£wªÎ’ÓÛ­âöÐÓìÅÁõ¹ÅÔŠ­àšs’Dnw=¸¥ZoƒQpP–ƒZ¬’~ˆtb…xX|hTÿþâÛ‘ÿÊ›’TÁ§|³¡…¥£m…]TnwHkŽG{_L€‚UŠ€V¡S>í·‰ÔÑ÷¿ƒ£¹cmG•Æn€£MwŒDv‹HØ«}†«T ‘_}zR€tUZm=ymGs•NX‡3k‚FLX+lbCy‰NouGÃÀŽóè’—Ô‚£c| Zn„G†¾pÒð‘—µ\€ÂoÑ÷Ÿ·v}´°v“]ºm‚¯Z޲T ¬N„U¯¦Vv~J‚UqSd•>_t2ciFš•ÄiÖŸr¹²X—–U¯§lºg€£Z†Az”Gk†DS<*OiP•Wgl>c„@\}EŒfš»o‚œWŸ“Vyi:yoFgmLÃzf||N“{cŠŸY†”T•RmuNnwM †Z“£g‹‡@qxQˆ•Yt‹Kn†KsšEc’F‚¤`}§Y™¶m«µ{ºß™¸Ý‰²Õom¤[š£[гUsžTuœQk¢m‡[nk5L~67S0^rEM‚1+@%6X7[ˆb‚®s‡·tš_l…[}fx™iƒÄ…§Ë–“ÀMQw@bƒaŒ«q¨Id€Mt˜a‰£[n‹Oj†Y™°h’­hxª]lœ\oš^|Ÿ]e„Qu«zÏx®^k‘_u°^‡Ósßiv¬EMZ9@^Ol˜což]l™QMuCLtCTuP`„QkŒIp}CWdOf~jx”hl’bj“OOj;N|C9d=Bi/:U0>_Qt|{–¸­­å»lx“XoI\mCTnQpixŒOEdHH~aYƒj}Qds0Kb@2K+/=*->%4;ABGS&žlJÄpOätRÿ‘Zì®zç¦ˆíª„µ±Š±‰Ž­xhÎdÿ‹fÿœzÿ®—ÿ¬ŒÿœŽÿ“ÿŽÿ¨“ÿ»³ÿ´µÿ¯¨ÿ¥¨ÿ£Žÿ Ô—‰‘ÿzwÿ‚sÿ§zÿ£yΚ~—˜€¤«[‡Ámo›i–{J«a­ma™firNÇEÿÆeÿÿ£ÿÿçÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿàÿÿÿÿÿÎÿÿÓÿÿÿÿÿÿÿÿÿÿÿÿÿÿòÿØ”ÿîÆàÅ‹·×¶k¹ŠW|Ver1N‚>Tu6Zq3Zj2do;x„GnžQ`~Nh‘JUŠEa‡?TFvgG}‰Bk·{gQmV8qg;ZoC˜c/Ó†Wç–­’h|‘C†{Y›•I¡¢qt­o`•_‚vQœÀ]̲f¥V›oˆN9t\2Wv>@rAPV,3R&h? ˆk8qqEÓ’e‰}waqPaz@m;º½gŠ×§ a«°z¤wŸ¹q³±|oÒ˜y¸v±±bÄ匥® ®d“†e–Znnh/XS'\eBTŸNGp5žp.\Sdx>q“L„˜K§Ze¹|\•MP}4U‚C^‹G[˜DX8kBгrzºaG¤aGdhu)IŒ€^€5'U}oXB.Yx/p ;_œGWsIuK7FoaD>,se+éªN™‡ƒ‘Ä|ŠÎ‚“µs=oLaJn£]M—AWk,¸‰R˜dw„?ß¾Œ™¼t‘³ehW6u~KŽgµ”sªª{ÿÿÑÌÿÍ®¤aýyl´zbŸ]ÃÖ’Òü·ÜýÍËÿÊÓû̸븺ƛªÍxÒÂzû¾Ÿw™P|ƒJ¼•aeNËx`™ˆj…mSç´”¬±…™Ü‘yÚl¾ÇŽ™«l„¢ky~J¥nN¡¿€|‘Wކ\¹¼€««bÿ…ÿ¤“x³YJ^¦Aвd…¹cœÍ~Ár¹j”‹ayžV}oFs[@fpC[>keRS9‘—Qš“[ƒ~Pîy‰Ó»ƒÿì£ÎÅ|sJSd3\iCoYªÏo‹ÁY‰—d“´gˆ¤b®i‹ŠLŒQŠSp|V2AR9RYSf‚€¨Ê‹§Æq…œEak:ST8TYOgrWo…YcŠasžQ\nDO`?HR1GY:,E=59$:>NE\Q)8W52A5.H3 ?!/#3%/3"=%'I0!EL1jF3bq6lxTxQ]sPXjIl;ur@’iEËrKÿšOÿ™xÿ­†í³‹Ðµ·¢–¼Ž¦œx¸}pêt^ïkí›áž‡à•‡ÿ‹{ÿÿ¬•ÿ¶¯ÿ¹¦ÿ°¬ÿ´¡ïţ䧛ˡ•Ö‘–ÿ‰€ÿ”ÿ«’ÿ¸™ÿ²Œ¯§†Y”}m]b`>{wM‚—`µ¡aÿ¾zÿÿÿÿÏÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿóÿõŽ×쩞xŽ¡d¥®f}j[o>wMO@3Vg(Ro1Mr/A_,OI,gb3RŽB\]BTw=s;K€JMVB;[5:A(Y6 sZ2X’W†‰Tr–Novtr=Ql:M6sAÿY>}ê“£x}’I¨oEó—`{˜}~fW°xD˜¢x±›kΧ]à••‰¾|Urh‰O,Š€?hˆFAoE\Y(h`,jb9Ÿ‰T·œtºinŠXqƒS‰rFyiWb¿\~oWq;X‰XiQ:V£P˜l;¼«j»Ô…Ç™EhvoQ%Ò†HQdLVJ0}F$}•`]\|R9ƒ HD‘]TO'Fk->V3"3!y*º¹aX£ ;eG_= [wHQ†DKr:QxCSu:MsDMd:eoBY}:V^2Z‚KI[9XV1„S0s²nWuY™W/[yQiu/Om›š{‹´]Si+Mt4o‡;j©VŽ€K­§ˆ§Ø ÉµÌê¯Öñ¿µÿŨjå¨mŸåŸ®ÄzºÎ‹¥Ûƒ–¾l­Š]å³f’˜M¶’GƒCŸÁl§´n†‚N–—LÁžMÑšUŸÐj@oc>‚ m—hžÁ–ËÏ¥ÀÒ›‡§w« lµŸ{‘Zפ™ÿÿÓÿÿöâÿâÔÿĬÿ§_sN§X?àzRÿ»”¯m‹†S¢aae0~G¦`drAjpD˲¨ŸÖµºððݟÒÀ„´È“»¢s‰xG¨žkfs@{†SŸ§n‹—g«¥qÚñˆéyg•Bx¥V“i•Ãm}‘Civ?혎ˆ]}‘SrvBmmEeGsK__?f@Fd/pO`‡ec9_sNZVWoV_’`iŽeciws§{‡«OXe1EP#5?2=XUZ†mx›m´\_F_c;M`.>I-4OEQmL^o7=@.?O=Y}ET|J3;31?E?cW!Fv:>[E7M6/M**>2-A?-Z$42)>+!CC&Z>%SN&[^DOeBd^Aƒ`2ŽB‰‰Ps‡[•yd¸‹TÝz_ÿ}aæœsÛ¬ŒÄ¦ŒÑ–¸ |®ˆ†®€i¿sgÐz`Ünö‹vÿ™~ÿ®Šÿ»¢ÿ  ÿ”ÿ§›ÿ££ÿƪÿìÁÿٿ帴ڕ™éš’ÿ™žÿ«–ÿ¾™ÿÑ£ç™zžwMiVšZBÿ±Sÿì‘ÿÿ¼ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿéûÿÿÑÿÿÿÿÿÿÿÿùÿÿÿÿÐáâÒy±œfoƒNY­Oe]WS|G=jGEN+I^&MU!Ra(Jv7]m*Š…;U¦X[rHU‡HNa.N[3OQ4Bo3.R'S6kL!‚Y.|“RŠ£aeÂng•gZs4p]1wd@Í{WpÈ\‡yaw»XxmTŽ—C[Šej]?sa1VŒLkf=œo/á¯{Ç•yk£~WgNk\)Ot5•d8Qs[me9…˜RŒ^­¯nr‘uqHd•TIj=|a0ÖA‹ã¥šµ}QÂz¬Hc¤lx‘MšK’Põ}\†äÑbÚ‚YeQTe9F=è°JR§ÈxN[¿u‚N±™i`†ruˆJn¯`Y“`p‚Jp§gyˆZ\’OXW;NM5A(?U*NM"ph.Y€V¥c5\¡xMr)Jc&M9'Fm$xj R cU…$0`#@6GX»QLË BLAZ„4-T.F^'U›@CW-ZH,afCidEScGBP>5],{\'³»z«r‡R«l—¨†¡¥‚µÍ ’ vh·ƒ°f“Y2ŽGbLU`'D7*:<$`C^…DE{4Zc,zžJ^lC¤ù—¹^Êퟆ~\x¬wT~9HJ%¨kV·³pÏÕ¡÷ÿׯõÑ‚­v¶”WÅÿ±ÊÜ‚æÿ»Ùÿ·»ÿ¦Ù‰IŸ”qÌŒFÜÌ|®ã{•À^‰NŠ9€Š4—ƒQwY5Ί}¬œr u]§Œ^¹à¢§Ú¤¢À‘ÃҦܯˆ¹q„Wkµ^V{9^DÕt†óïÓÖÿÚÄÿžkd3µ}YÞ i×·hŠ€HxSU _bl5}ÖghˆNvh>¿„pº½¢ÂÖ®ÌδŒa¶¬}Ù·¥±á…¿a©¾‡qHqœYnyK¡oV×’rîŰÁéšf­I›¬lˆ¤_„¡akBoŠMž|X¹ŸtuŠI«‰e£¾euŸH„±^u§Lq’IuQ„XšÄw€§Wˆ§b~œQY~/O{?qdAÍnˆß]^y9OS.k€H“´al}M~w\ŸzžË†¹pl€Ju¨Q£Ó|™ÎoÖëƒÊÖi‰„F¦…MŽº}…Ódp©Yb™Wµ„r³Wœƒ]®ŸdÑ”yš„U•¦`¥­{ÑÕ’ÎÜ›žæ~ho\Бz´d½‘wÝ⯺{¦­{«¶už©a‡aº±|‹ªZzœZ–¨i|•CyƒSˆ kr¬Z~©ZŽÌv©Ö{Š®_q…D˜Y’½v‚¹]¥Sr}Y~–cЦVm’;o„PƒŒP~‘X}]±±„–^`¤o”ê}x­]c–]eŸeS=` Tg—D_jFo}LGU6a}IMzG`Q‚­j¯‡ªÊ„„¨ep•NcŠJ]w5^ug¬ÎzyŒAk{Q€©‡Ðxo­Q]‰Fp“n“·ˆƒ¸muŒL\‚Mi’O[‚Xvoнs‡¦exŠVoƒGMd1U}IhŒWb>MlVkQ_’is¨fhs„­lvm’Ë™µáfd€17A4=oQb•[nhy¤„´Å{|©[hŽSTr@Et3@c79^DAl38G1ESEThQf‹V1J(AA1hZ/€|=PŽR>oU6Y84L'3?G-^QHq5;RA;4/:?&@A$O> [Z/Tj8_p8xi>‹ƒ@€‡Sx{U„‹c”\•leÂcLâtQí–uý±‹õ°Šñ³…Ü®“¤”‡Ÿp™lX¹hSßw\ÿoÿœÿ—‹ÿ‘•þ‘„ÿš‹ÿ¡˜ÿ¼ŸÿéºÿõØÿäÆÿÆ´ÿ»§ÿ¬¤ÿ« ÿ²Ÿÿ¸ ÿÓ©ÿÚÿáœÿ÷Ÿÿÿ½ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¤ÿÿÿÿÿùÿßÓºì²~¤—W‚^u`Jp”Y€SLš]O\Qac3CNGY69c+6H JI[]'vy0–Dm—^t…SXžbRu:ON6ZZ0Hs6CZ-CL<‰L!h‘C{tO¦‚;®~u¸oY’Y¨x:¥®`Š£…a’Z—…V`Ë]|xPn Al„\\W9uc,WiBHh:h\$šj7¸‘i}‡iŸ€`p˜XZjGiz8ci5³‹NˆŠmÿ”jš®ŽdŽo¥s>tÀt~|=JGOe7%¤Š>°´ˆ¿ë¨‹ëq_|£`ˆVcÛV»f6ð¸}¶Ñ¹n²—oVKXmLki4uPP–a]q8KgI“Y)AÈp=H0AI#Ò¢BQ’šL\/VL$Ot,VK(ay;;,EDMA P[MžIQW)X«F^7`Lu€[hL=jAQR,]`@}lTRpF•œOŒ¯|§u†’o‚—Zh‰WFr4N_%uœIˆÇyR²f€¼ŒhƒQt’JJj8md?m•L³³|„ЛÅÆ†¢_’Åx†uMþÈ’š»{k­zƒR@u°ƒ“TY{4;S2Q)!|‚d®¾ušÃÂö·wÖ—¬ŸUÄð¡áÿ ðãšëÿ»©ÞÊrK¾Öx³éÇÙn•­h‰´XW}E\c8|`Hnl> aR€‹F€“Z“™[„€<ÇÞËΞ™Ö”»Ê†×äÉÈÿÒ†ÿª˜„]sÌyuƒA4l.ƒ,%Ñà¼Øþ¢›®P‹—QÛÿ—ˆÿ–oz7ɉcNƒCQ^+PA€Ag{R ”q„¨wÇ©‘¢Y…€]Œe{žWŸw_‡]§±l–“R¢“l†ŒS’˜W©Rί¹ÿ¡ˆ²i‚¨dq”I•yNŒ¯b—‘nÏØ©ÊÿǤû¥‘îxøÿ´y¨X¬Õ|½b˜§j¼º‡¥Ày°¾}—ŠU˜Ä`x–Hgk?¨Èƒ— i µTžSw¼Q_wH³o‚¯r–¬…m‚FwpN}nFLo~U™«n~´d–ɃˆÌÌ¥ÇyU†BlO6w{YPm9`qPŸŸd{QŠ^»¤mtŽxµß ¤µqŸ§…âÑÆÚ˜Þ·z¯¹q—ƒTože…½n¥¨{…¢GnDc{?qqPu„Vx„Ir˜I¥¶|ªÃc‹ŠL|–U‡£hŒ·i~¨f‡¯\m€–n0`qF‹jO¼mAªz¥nnº€¸˜P¿Rœªƒ–“s³³WdÖ‡p„W€~:e“jUe6|7^yQG^Db\-rH)¼†^’{gv›hœp<¯˜PeÆh}mI˜ˆX¿ƒOkh|Xd€[¶“H_ I]/)@.6v¼eÊ[¸Ø }Ô©¤“UtÆ}|†hj¬O¼jT¨“kõ¨{•¾ˆž¸Œb—{zn@§¥N[€Rc0HV:?^+“b.`°tº”MC‹@Z2Sg'[g5x…P’Ÿa¼¥}l¤Ž9eBMS&zh=¯vY^ä–H‚OK[0€d/GpWAL&*N1H0slAS¥[k^0cN0MY0\R";D!VK'@K"Rg%]"*(SEE]&hy8S«`x]-\”hVsMOa?^t.e{:Oz7MK-nn3xFg‡bb”\ŽvAr½†|¦Yx^Ak›`^ŒM]p:z­XU“Xrm4xœTL NZŠ=|›Rdn1Šs8tL«¯S˜Ç‘—°sd¹›Ždÿ¨m¯‰c ø‹k¾€=¤NUa5n9N‰H)>2!9&¢_F˜_Í÷ŸÉô²v¥u¤€cÅý¬ÈÿŸ¤¿‡]J7†w>wÆXÀµZÇÿ¨eªUN[0VY/MU0]3+‡Y8ƒeDytHÀŒg•‹rb]A{d@Ħ†´é¬Ã¼~öøÆÔæËÿÿÿ“ÿÁ·Ü•¶­ptŠPSM.¿®n¶û…Æï˜…Ôx¿ƒr¿§c}›]ÿƒ‡g¡dYU*r³VA]$toIcjGl{BtVfŽVƒ¬«Ú ˜¾p¡†X­Çiš§et¸b’©tƒ´]‹¬]tˆIŸ¹mòÕ—s¥Te…:[z-•QóÂ|¢X¯œ{½Éž›ÕŠ±ÏŽ´`q£P©Ìy‰b”˜e™ƒi¢©nŒ®i ¦`{}=ƒ˜KDd-ñŠ”—¡Ep{9`~<{Mz¥T®®•…±yw–Ue‰Tƒ¢rc™P±RyƒL[`/ƒ™Kz¸Mr©Szºcy·W_‡7a~Hp}T¹Ô ¹ÿ®›Íz¬Ô´—ÜojtI‹ \{šP›WŽqVwvMiŠEvrG±´•·ªv£Ô‹Î¢Öÿ¹ÆÏ›Žl²Ò“¬Õ‹³É’ÐïŸÇhj@j›BcŽHysEch/^z/dr?¨ j«¹]x}Fu…Htœn—Ài€±`§ÛwŒºUy–Yg—LŒ›j€ª_‚‰b‰¡e‹°w—¹o•¹~{ŽY˜šKu T‰´`i›WŒ½~¢Ëun:>4+4,]aZŠ©j€ Vk’WU—^t¢kx ahJeyT[l0EP4MRL“¬ƒ‰ªk‹­asBW`;Ub.Na/Ug?gtPp„Mi„Um•`‰µv…ºcf‰P`…Paa¤Á“œ8Y}*Ov-K_AYs=Qp0NfEdŽh€¿}Ídh{J\D_bHUoMgŽ`b•au›oˆ§at‹S^‰Io›`vf€°cpœ`€¡i€§f½kŠºr¿y»uyHLWTbzf|„y¸‘Õ…šÀr‹¥j†£msžejŸaln8vwWgˆZ[ye'‚l,F\+8/-6":4LAdL+Zt4:OIKJ^7&bP#^p2re?Ÿy=Ž˜QV¹}]kok_7b\0XcAkJ;ah:huL‚bIÂf<Ù˜Uñˆ}ÿ‰oÿ§}Ú±—¿¡½ŽµŠuª„m§ufÊv`ÖzfÒˆlωxâzpÿ|jÿžxÿÀœÿç¿ÿìÖÿÎÁÿÓ±ÿÞÏÿÙ¸ÿ¾ºÿ½®ÿø´ÿÿæÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿúÿÿÿÛÿÿýÿÿÿÿÿéÒâáÿ¨‰ÿᎃš :ez#A:,3"U6qV#WhH\zH)kG>4'OHgd8K~G9X;5:$>@"UL Sr0‚j+^“Z]w>XrDVm:[:Xg:Xu:[h5k^8Ÿs4h}WnL‡gD’[IZpk^r”T˜‹Etˆl…xY‰ˆ>U¡mbkA…L¾l{L޲Sž±UpÙc°[¹˜K†©h–«v‡§j”²g¨°jzÅ|¥cR™bmrH‡rFTkNˆp6Ég]”¯a4wZx|RšˆP‰§dz§g‰‹I˜jrÛ‚m«p’’JZ¹eÑhCrwªQCךbpÔ¶‰‰Xg«hD]CGG&DN*Zb(J&°ºƒLºŠEcq|BknEtyFtƒd“ª‚v•‰±Ò ¹ç£ÍÜ›•¿v€™Mn@p¨[…¨[m—c™§m£š{ƒdFfT;GN-A^?enOl†TsŸyÓߤ¬Ã…~³omŸJf…LhŽDd‡QRnJ‡ vƒ³jˆ¢Zr}KdpEzˆIdŽFU‡Vz§hx“bx¥eq¨i†³t‰½cc—Ll’Nd„P}œ^{@Qw)Nx8Gh-K_6Pj;S9Pk=LWl§¢¥ê՜Ưehˆ_]zhz›dq~WOH0UT2[f@aiWF}dDrn1SJSN*_n/G€DuhO—sEYš]FhqJDEYE(J^,ZTBgk=£dEvSXŒr|XOdj6QuOXS;vT7Z„B|lY´~E¬¤S¡ƒfímaÿ‚[éªvÇ šà“{ÊŸv±•¨Žx¢†jµwbÇ~`ß…jþnÿ‘qÿ xÿ³ŒÿÖ§ÿéËÿÆÅÿ¤ÿ«ÿ¼©ÿ¹¬ÿåºÿÿÙÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿëÿÿýÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÖÿÿÝÿÿþÿÿþ¸ú׌Á¾¶­Ž©Ÿ|A€l>RF87+KE"Bs3?S,6B!T; Rq.7pO¥_FwYk“\hSw‹@n‘[™oF_Rq§Tj—W•ŒJˆºh„²zv‰]´Nž¸q†­p^RO]DPS.aq8f}C¼}QÀcp”gxZk„copTbnD“r5y¬ah‡P–xCpTw}S{‹XXŒCx{4eIšl@…‡]v†eyd;|ªTSr^fR+¦72‚¹q¼‰Q˜ìÁH•yDO5.8);0@[ §f0Çœ„wª„;ƒYFQ)G&Bd*WM2ʾ\’ÿ®FUa[8P[4>I0F6hc0'aF0EN$C< \o9hmE{°TeÄrl¨K¡žZ”¿re­Ub†:lH„œDh–@P‚LEW$Ti0my>q[F›‡HwñŠàÿŸ=ÔsVP ²LAàЬi¸•BY.F_'tƒ;¢pq£[y®Yw•PquN݈fkö¬¯½ƒÁñ€÷ÞN¦Qåá’hÆw‡§aŒŸSumZtB U‚}I€y>o†>YwM‹Ò‹¯ÕžÉûþöÀ¤æˆ“§UªÆ~}“Q†£g¹×±ÄӉе\¥Y“Ìg~¯Tj™H“±_hŸLšËt“¾_Žza°ÿsÙS<\1\”Z†˜»ç°†·f]˜Lx£Zp²Ws[£ª”ºâ­¤È{‚¢]y}AskJ˜œ`vW‚R…Ÿf€¶iw–YnžaŒ¤o™¢y¿YwbP¾³”µÆir Z…¤~‰µspžUok>Mr5LCd›Aan=zkGaNŽxŸº¬¶Ø¨¾áœÛ—ÚyšShˆO~¥{›Ø{¨b jq`u…]™i|P_u6E[3I]9\jOrŠ_˜šs¥fƒ¡^s–Tx‘ezmƒ“`~¨„˜Ã`qŽIh^`TC.Z5“PTY6ll.e“H]jFG[6EO,ea3T|>JP*ra6gFwb?ª|CŽ˜Q«‡[cŽ]s‘IEšU Z8Ô±X„ýk €“A…„`c—YOpUƒj+`i@Xn=Xs>SV5JO/„T.‚ƒP¨°}›eˆyG`^MZVDC]2A`(l\ FuEzj3fvBZ]Ult;a¢LV›ITŽEZu3P„>Py>Tp9ps?¾ƒPcèŠMeN„C3¥pM°ÕŒŒ½’[š…H6@A(YFUP*E=jn#Ô‚QÒì‡ß ©hŒæ˜ª®‚“½Œ‚dœZoŽa—apªD—XUR05[1Ï<"A™bAM2+8,HCZ`0—H¾Òƒžµ„ÿ¦L6jb+FbCTk*Sd4p^(ƒc³ZYANw;86%OW/â¡`·ÿ¼ôí“cÿÂ2f0.-t'Ÿ²ƒbbN¶ftp.´ww†KT‡ADK&Eh-½m@“²ˆfŒ8«¢m}·F”µL–±s[A,_:*x‚M¸ß…jÿ„E£Dg¡Sf÷xec3rs<„›T³Û‘¶{¦lU©~dµ¬p¬Ë…ÁØœâÙœµæ›ßÚ¬ßïÀÿþÖ¸õ½ ·ˆ”Šh¥nKˆoO•jÅ`|ŒXDO+^a,¬€g³¶t}§bSl?C]8aS³Ú¯ÎêÏЉ6C!QP0jOBveV©‹b¶¥ƒ“s]Çžªžt{yM¡ŽeÄ♈²V}~LkƒDa‰nCŒšQ‘\bŠO¬·ŒÌÛµÃà¹ÀÜ ™­hqCSj{Hk¦Y­¢ˆmšR¸jvœS–R’TrZÉטÐu|]g‹DXQ3ƒz\€®S| Ob–i¡ÒŸŠ«TeeLÇßh´JjuAWu?rzi¬¯qof@w•RW[9k„O‹–M™zGs§Y|©Z€ˆaisEq•Jj›GhL‘sZ–`w¦c…¤gŽ­i°~ˆ’kˆ•kv†N\w8_Ln£Dg|Q}s9ijKj£n¢»¤Ã╕Ǡ•§Æ…‚­p{¨uˆ¸¡°Þ”…›az¡˜µŒ”È›ÔÓŒá£e‹KhqOf€;C\6]m>jk=dxMzŠOkŸ xˆŒNrP‹tªµi€›ImvCqHj|]‡¥h„sO~t>Yj>jwH}‰FgI]|Ga‰W”[h’i‹±dw”B^yCr—Ty“Lz”Rc—]”»¥—GPT6gY@nlgš´gq Y‚¹ZhšcuŠ]x}HgVp“g¼j‘˜[}uJklAW{^z¥gw“Zs RbŽKQ„S`šZgžSi};H_=TsIj‚KUnJbs*$4&+EJVyNasDR^PnU\¨z]ŽvIaO,bn;j}IlpUqrQ]{hnojo_FmyLœkXŠœ\N©v2h}?DBWIkQ+|n;—oH]ˆ[^um[WAd`8w]6€b=]bAYKNzO8›i9“‰Kp°imtgcf=JYAi@<’U:šjJÕvYöˆ`ò›~¹¡Ž¹“…·ŠgÁt£±ƒœ‘‘ÕmeþtWÿoÿ“~ÿ¡„ä´¨¿¦§­…‹¯‚yè‚„ÿ„€ÿ¹“ÿò³ÿÿìÿÿÿÿÿÿÿÿðÿ¶ÚÿŽªÿ»¢ÿÿÅÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿàÛ¨ÛÁÕÿ¯bÿÿžÿÿï¬ÒÖ˜–|È—i‘žu{™vfj6xbGH4QFMi5Gr@?Z6JN+IZ.>]2WX0K{1a]W^/Tm@ga9:ŠGL`;\\*;u/3L0PG(Z^$Lg/q2ZD'ˆP(žØ†ˆng¡UB|<¡] WŽXQj3±\0€¹~iZ›¸dx™ctL>˜P6R$LX1cH£že—½t]¼~JZ-0h-*4£W,žbg»j^h"o—Fg¨Um€FŽBwÎxYkATn0f‰:pŽ;|•@¡«DUt?VK-X€9m’7·­ZÏ݇»ß…ÿØÿÿÿñÿÿŒëy¤Ô{Àë™lºo{tPt…Bvy=yD'XH™[Y¥Šn§§t¯›x׿~ÍÍŽ †]owCtxE­‚Z½_¡ÆlDr+D0"aU3™ƒP »ˆ„Ìq†×gIT0\8-ƒ”xªŸ~n„`Y™oHp9vH|¨=JY0m˜Km…Y„¢a‡¬`g”J‚”H“•Jq—ažæŽ—Ñjž•xV8Bc(/8 G\,HM4ÌOk©•d{¬Xb‡H}Œ]´st´Pq¶jy˜Z^„A_t=r–LqqUŠªDv‘8t—L”ȉœÌœ¶è§Ð×t¶Á⊴¤^|PŠvRƒzO q˜ÛŒ‘¸xg„N\8cp^}­y…´|¦XSrGk‚`œµvž¨\n‹Isy]’l’”Y’•\}9EN*C^?bHb…So…St•\pYq¥mªVm~8Xq@bBaCXmCn‹V’^–ŸJVg9[S?jx’¹bz›a~£Sm…Mz‚NouNi{cŽºnލa~Xqb9ZoHVj[tˆIarLo‰[w‡eu ht¡`yšOX|@ExDN}DVhEPSaŒCIv=D{LaFVx7GJ*EJCdgP~mTŽo3bTMƒdBYROKCNQ93cF:BB=S+fW;mw=D‡\/glK;6LU XT9em8nh=cbi}B‘vJ“‚M}kNjqJyXE•a<‡}Ke^ex_‡X@]s>gpSo|MwsR»fJákI×…p¿}³Œy¼ˆjÅ“mµx ¦€˜|¶lUìfOÿbÿ–sÿ’}ÿª‹ÿ° ÿ¦æ´ ÿ›ÿ¨ÿÄšÿß¾ÿòËêëåæ«Õÿ—uÿÏ‚ÿÿ¸ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÖÿÿÿÿÿÿÿÿñÿÿØÿÿÿÒçÿ·Î²ÑÁ—ÿ¿ÿÖ‹£éŸf›­o†m\‚[l\Gr‹Xc¡t.‹_'3?'+N,Mk77fLS:YQ6Ib4eW)Lz=jlZcx9:m8kF5O„5IQOG_+=e12[$:CAb%S])Mm+fo8RoCcU9hf4u‰C}Dt{ReWGX¡Nj‰JV“7QuBcz@U~@ev7h}EOe5cX7[a.zQ3¤hK]’pQeYmk;_~9ybA@‚nOh.=k0>O$]n%`C_{FuŒD€¡U“T~«[a¤Vp’Mz¯Wi°aT‚UXv9Y{=Xk?mW5}•NΗL¤ò­ƒex’\‰qPj¬Z’žO˜ eqYc•UFpC/V*DH Ql&GC]6¬_ðÿ¡5Ÿ?B$ÐŒ>e¸šif>3W$?T]!ƒ†I‡dUZ¥iay:cq;{Q/PO6KU3KC/ˆz2µëˆjƒuX„J@o7jQ!del%>€1T{1Zq8\_0„¦mm¬iQc9W\3n^8lmAd‘N™‰Tu}E^pAT{@nb8Í‹W{ÿ¢Zy+y…Ga¯qŠu7††Q¥š_nN`„>z¨U†¸cIK(ž¥\ŽÇp˜Áj„°UеW›»h£ÿªÛ{•­lù²cÿÖÜâÿúÊð¬£äœj°m¸ÆpØÿ¨mÿµ>N%-/4'.',2tM.ã±€¢¤`’¼pnyJhe>U^6W=!–H9Hv2F\1”^ž«mgI4€J¥ÀkFá\A2&g•¢[R}VJb?OUfb9slDvnIxkP•vL††RžWš~F‰ˆ]|yXisPjvIgkDxmFio9kxZWeWhWGtX:žJ:ÍZ:Áx]©…o¾kî–`Æs¢žŸ¢{†e›ibÀ^RßmSîvkÿvlÿšqÿ©…ÿ±Žÿ¸­ÿ»¢ÿ°Ÿÿ¥˜ÿ­ÿÿÿÿâÿÿÒÿÿãÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿòܯÆÎÓ©˜ÿ©ÿ´ÿÛªÿʪÿíœÿãÉÿ㯖žhW|szCAwW-@E1#”Bg¤zf•[WuXU‚IP€?d~1Ro=~k:–ƒG{Ïn~¾r_‹`hŠ?w”Nk¬ac›W\oF£JQ­}bqJ[p8sx@±|J«÷ƒ…Ö¦O{Jgc+“8Ž»de¥a‡|;O}_.9/EQ#Ug1y•LR|\onBæÙwfå·9pSaS)‘‹Qi©g`kIƒ„Bo¦hKhIY?-XD/yW.Ž¥Q–yXT†\zm3paCc`=¼N*Çí…‚ÁaÈV?}AERai'Z]4‡µbbr_a–GSxCOw)<8.hLWwMIrCSž<3h0Wi.‘DÃÚ“]‘lu‚Re hi{BwwOn—`{²h¥Ëv{¦^Q»\RŠC’‰BŒÿª\šWVƒATo+hb%pk(U@uR(xA0™T6ƒ·j†jAœ`?«rZsyN^u@bi@h€F|ƒKs–G†¡Xš«g–PWŒCgv:_g7`Y%;M%fk-g¡U…­T–´pz°u^Ÿf»²uºÎ•z†JN«†XÎR6ÿ×¶egn(JK(RÓÞ:W(¡]V`†INU>fD7imG¢rin™V•…fqxR~€R‘‹_†“e˜ž_sTx£_”µjg”Dd{@vˆMk†B{³gXj:ËžvcZ/ƒŠnÐú¾Öñξ𶖾~Z†Cdl<ƒ‘_šS©YŸ²‰Óö¾ûÿÛ½ÿ— „e¡‘o¥˜Z†ŠOV®ÍqÔÞ˜Ÿöƒn\L®³§†È}f„R}dEµ·qš[– jd“@j”@k‘:Y„,j8vŠ:Is/Hk/y“h’¹}’³™Å{|²{‰º}—¥v·ÚvšYœ’jÂÚŒ¾ö‰u¡L:[*_a/Zy>cPdzHo‡S™¾kužMwƒMn’grOPk@[O8U`6hŠc…‘htq»yl¹ÍÿîÌÔwk‹T—¿p£Õts®AKpO”Á­½÷®Íøœºðš¶ä€kq@NlEVw6Pu8ds9CP+TnE`r6}vG’¦†…§C`qE`xHvƒZ„Rm{S~—dtRvrBblG`kZ›j€ŒK`Knœw‡®‹µ„¬¯“¨”SgWQ•˜qy™j€¢okw@{dXŠ“`„œX}{GV^K|‚^rsIt—ì»q‰•c~§s‰¹y„²dn}Lt|3Tt(]y-Ob?_x?fI~™o™Ë{¬É©ÎƒŒ¯YqUkrNh‡TcyEWiJv—v—¤kƒ‰KXYq¡s‹¶jw‘Qe}KgmY}Pƒw_››d…Uo¥QZwVh”`e†lu¢k{£eo•`nŽSkF_Lgv?Vc1QX7V^HyrKe€hInd;dP-Q:+;.@)%S=`O-‚g@xˆM~›h\–fE‹}g]Qgu4G€P\dTeq;uq?¬cIuFlkg[tNerLt?±|Mƒ“TN‚eKeT_^/n^5Yn;Q_;POEIDR<@"uAA‰=7:E6?)G?$S^(1lN?@"F`"Ud%Zv;_c1kc1SzGpw<_ŽJv†Yg©]g™^y¢bu§iRŽefqA¹œ=Uelp7lOK/qb4™™byµ‚jY?gdA\ŒFÁšI«Ö‡†·dN•OT-Ji%bo'M­^ZL*`X,UT-‡zB]o{GWz:k‰GQ†?>^%>U#Zk,e3‹`>Ÿd…™f­»~|œsžµw}¨`‹§Yg©[@ˆ›’NLA°„`w«S}g?µmO”zQw‰T©ph¢Â¡x¨qr„XzdEkzE‘œhjƒM‡Ž[{•RZ‹@zS9Š‚N‚¹iÃn¤¥ckw*U>2Ä~e^‰\‚3R[@†^acBliQx§]s£mnIN\*Yl4]g7c|=~“f¶×™¯æÐàõ¶¨É~®Í…Ž›Z™Òm•Ñ`T~L Ÿ¥Äò’®ó¬­ß‰ozCikk€¯ˆ‚œ^Xo+HM$HU#L\>fr5UPH‘¸—~ HgwUg|>lcAue=T{Ju›mkŠ?Z‰EhšYq™Z‹LJb4Tqh›¸š¤Ã¤²¾‘“†ï¶pcdX…z“²z”³{vRs|`ž z£¥ZoxHhvr¨„@XtT£œl—‡=XlNpj­}{¨_s‘Oas(Ga/BG,A`Fa€Eaw:h•Z†œd‚™Ÿ¾q“±zŽ´en¥tx©f{Le€Qq~_‡ˆYipD\as ˜®‰†®ƒˆ£wœWt€Ul‚l¥ kƒ¢j™«s–•ip—fl¦t kg†[[‚ViViŠK`h9\\|zGxU_Š`P{fi[Mr}9RxNRoTffCco:§XH}eAglYftL~qIjvA€pT”sPW|QSqQSi2SW4M]0XQ0J_5I]F\N3R[8[[BZK0YG5XE-—D+Ñh5¿‚XÚˆqÑ™sµ ~¡«Š”‚~qb…aN–gNápPÿˆ]ÿ¡iç¯Î ˆÇš{ÿ’jÿ§jÿè›ÿÿÝÿüëÿÏ×ÿð¹ÿÿÚÿÿ½ÿÿÿ“ôÿ²‹Ž§}ÿ¯{âĈƒÊ­o¤y£™ÿ£ZÿÖyÿÖ˜ÆÔ©`ˆ,8X*!)_?6q3?@'*((1 2&&/*:0->:%?T&AD3VE%??'1I)>=.>TPH&gE!JP3+PP)31-oA6y5Fl$Ti*c];T&Nj%gŠ?.V3>C#lkGzªdy‘Sz…Rf…EŠ¡a–·b†ÂoD„;„M1‚™Wo˜S–c=€Þoˆi>qisW9ƒG*@*¥b;š€\¹±ZR6ŒcDV(J1À†£ª‚œfg‘Jh\{?X`2`nDªqPukLeZG„m¬qax€g{Vµb™¸Šƒ˜kšbÐËž±mµ\[6v‹F_‘TtoDÅÆ’ŽÐu€ªT…­TXh.fyFÀt}«ËÍç˶Á’€­_lžVx“\ek9j˜OŒ¸gršVŸ¾z§Ö‚’ë‹aŒLešFLN5’WLs^AvT>dj>ž¹u¡[k€Qhh­™ì‚¡{[ƒJ`S8ŠSy‡?€‡9”G˜ŽF|ƒ9Sm6Fd3e\;zhK…“Nl€CygNȳáÛ€¨¥U‘˜P™˜j~ \¤¹m£–i„ŸZmtD\a?_„;k‘Qm–\e‹IQl9b~Dƒ•]‡•gu‰Nbi9`|?kv:`~;V`Bgkz´Â|gSŸx´¿k«[¦Ôr¨×^`yO™­„£ã°³Á–¢¢]`bEisZ‚nfmc0k€a¦‚Edz@\wJgvSe{Wou]}~HYv7MiGm@2`J^@:cK(Yy=PrL`fGmh5li>h_?]kCRnFjd@d\8giAW{I\UFOc2Cd??R5CW-uI.th/{}M…wQbI^pQVYDZS=SU1fN/ª].Çb=íƒWÞ’sÔ€µ•ƒª¹”‚—pb¨qZ³Ž^â–jÿ›oÿ¢uÿ¼ƒ¾ÌŒ«žÒˆp¸‡hÌrfŒ“bÿƒÿ³QÿÓ˜ÿå—ÿÿæÑÕá“͉}®ˆ¤™w»¥|­¥„¾²mÿ®ÿ«aÿ¹—¸¦yD€ .YMOi)P>-3&5 !'#$2+#79cP"q“FT„Z=Z@DF(IH.PU2Mg5bS>Ua5ffAC€DNbCMi8rm5KwIkd?3sP-A6';D63]$R=#Jv+]P1pI(RlAMm>Hi,fr3Œ™C¨ÃZ’ÒŠwȇrªoiŒcZ}VjuDi‘?L‚o`h<}‚9pšf~™^`qhlmGqj>LjXI@8_Y*9[9GB,bK#mv:„SihHT^Gbl1=c25F'H>¨R"¢z?±›‡‘ÍŸ~¨o[Žn^†TpˆKj–GZlD0H9/=".9"24;A=L&2M.GQ!ºPZè‘qƒHYpG1f2DH Sv/hg3NwIlb<‰p5‚wPÏQ—ì«MhnWi/Ok7_l7ÓuI©Â“TKá|Wšžƒy_“€TŸ{Yÿ¢fȾ¥œ‡mØN|œm«‚=”{FX¯ƒ_ŒB œ8|ŽH½™_c³}uY/noBwXHgiJ”N†Š[@r@Ne*d€8^ˆ9Kr/‡n2€k¨žeaˆR·ŽGVÀˆ€pA„´hÏŒc@EzOgT![t›Âi\²lTšCOo0Js.1L6‚8˜Ëiœea•O´„NrܪHŒMKd DI"w~An“U†˜\s•K†ªi¨k¿°‰–ˆY‚zOŠ‚N‘`“Ñqv€JZZ5sgDž|T¾ŸqÈ̳‹c°šdvmK§xTid;¤xIˆ5˜~A•Dˆr<|=qŠ>\‡KxŸY¹m¥ÿˆvÛ^^‚JѰ…¹Çr’šExNœ±v« nŒ“[½“d¼¤{“žcÑÅ}j—<††P°¿o‹J|q9at;ou>rs@ƒ\›ÆfvªT…´KhG„c—²Žo{7=3"]Q;e…?ƒ•X—Æa–­UmžSo“^‹Udz=MY7QHEphGNX$94'RO7Ze2ET+JK/MG4\e‚¿èwcu3JP0\W5Xk6`s[—”r˜Æuвk‰¿m‹”r’¥nƒœrv©pu£z¡tŒ©z‹œyœ˜}Ï´¢Ø¸l[‰iƒ–y™¬tˆŠY¤˜p”ˆIdyR¢SwmJˆHq}Ds‹Pˆ€Lm‚YlˆWŠ[~„LXwJ\vVjŽ}²¬™Ö»rw‡KgnR–†R‡QmzEdyR„U}€No†Iax,Cb0Af8@g=OtBNrdr’tuŽx‹°¢²ŠŸ¹Šµ¹|™‘SpOpwKjbF`lQe€W`\u•fzYlŒ^o¤fdL_y?^u@_kA_†Sišcs£ZV€eKm`C\In[;…~3‰‚Jq‡VK”],m_E:GMO-;_@=J=TE)T['c^/XiGUgJd`;ToÊ›Oþœ^ž‚ÿ°‘†¿jv}mùˆ`ÐÁr®½•ÿjÆœd“{Ly]BK !' `7({662;$=""='BRK]$lf,hAl‰SPwJYX:lU+jx\-ii-h‡EX|KWlGzy6x­Zz m¬j·rx·}€¯jq°pq£mr‡NJxjSN8†y0´˜cY_>?SGU&UC*M_:LwMQl7PM1OO0bk=b{>U_MGA+T?I5UfCe_-Aq>w;*“Kÿ•{t›¸d?Œƒ[l¿_L]Upa4wšJG³O>x@Bs>@v8@x0F[&Nu-X_+^o8vO0F–iH\+@a3GS%be0]ƒIoJ+d„KÆ`6Ó—^Íî£R›Sl>ƒ[6U|JPb7‚~E¸h\ʆZ‰qgˆ]{jFv„S…OàÓ{ž‘|mzY£n@…ŒW¹†Oš~Qxoq}@hŽS\'Ko.ai9|†M^dA“b4•mOR³€UtA­œNs´~¦lyO¤Yr•IX™F^ƒ7qfMœ¬evŸKc‡Cr™MÑä ¬‹S|SC†¥oGe4kxObIY‰AVyCqtAQl%br5j‚Cf•D«_N‘_TÕ‹…ƒ³Jx‰@Å‘}®Ž^waP¥”fòÀnìY›VH­UU–]JšOH¢nR{C~|G—•Gœ„?uz5“Arm@™PŽ­hš¥ZŠœuº„µÏw²ÏbÞ¿x±’X¡‡Mx„GŸši•³Qv‰K c–¯z˜­m–Tv±Wp­kœ¹gu|;X~1Xw@fy4XJ=©}NxŽCrŽMt‹Hk—L{›s««jwc)dnJ•Å\¤¦M©°_¨šS]{<]~J„—`|‘\jzQ\_Heq8EO,BT+AD,Tf5HTSDJH9O`/dd0P]u\5nn@G‹\]sVHsE8nVHG?HM+NV2bd8Nu;KqL^_@Um-N_:[a8Ys6G†DN^GEZ7BR6GU0M]+[S,JY0Pd>_Y5k]5htGagJvjDƒK‹‹[^’i^r^Nj=Pf>~W7µp/¥ˆP»oa Œ]¥…rvTšŽ`‹¬f—§{ˆ·w‡©zœ‰_©{Pª€U—‡b‰”ZÉ’X×rC{ªt€ †š™J¹TŽ”držZwbtO_‡XwzTÿ_C·®I”® ¬‚ZahLkiH"yH 9!M)_q%8mO7G6;/$"77"IA`X)ox9sE‚˜X]°n\rZbmAhzCfq;ekAUyVmX>N_9SD1nA&ŸT.¸—a’t_e]pbAkb8UaSOP6LY3YH'cw;Ts7k€=R PTsUZ`8VR3q)g eª^‡¼xŒªiz»xq»€w«nt¡i^nR+aXF,}i$]„aE‰=2HBMI&TQ6eX3]g@JsFOeH‹HelOa[\W:HX3_S-[{2^aAMh7S\?ŸƒH~…|ŸuAPœ^jQ1g»K8AI9A)QH,ow9 ŽT¢á~Ò„†bf¡]|JLqPRY2Z I‰|9DJWA&:U+ET,[n>d?LP4 d1y•vͳ]÷µfqcRcbQ4Ma?|y9”€N†ƒQÿ¦[•ª–…zYaAqfR¬‚LWMGÐG/¸}k p¬[Ñ{Ž•^tu_zqGt‡H‚Œ9·ˆN|­ub•YK}Nb[&ÿ¢X”Š’guMgjBCdE‘LWt?jw9x‡TG€UFH*eH%xk>_™opN5ˆyD„‡8†„FˆžP Æ£ªŠ~\Kc5€g/e„T^{@dzJov:V‘Oqd,™³ii~PgdF}¢[pU|QtˆV­º]z·t©Ê~´â~”Ô„¬ÚfÃiE|GU_3yu2•¿n_t4MzAhxXs-Sq9k™E‰¦y·Ö‹œa‰“P~´^zªY…SwzT¨§{Ï´ƒ´°`]BwS>SG/[94SJ8yuO“jB†}I¼¦Wg_0|tK‰‰OsvKƒpX¤‡_]]@u‚_—°|Ž­f‹`Æ©m†¢b¤Ž[‡IuubpW—¼p{xC}ŠPœžu‘£[xqJ}~LrWŸ`u“UX†Q~¡Z޲l£lƒ¼{v·pk©Zh…Pu}MvŠK’…P[b<\]LŽ‘r‡¤J{‹\‰dnf^–bf—es‰]z‚a˜ …¼Õ™šÄftšo«Í«Íÿ“¨Ò„«f‡ŽQ}ƒZ„‰gŽk¤Ž^…qNhuKkwa‰•rˆ“t¹Òš´Ðk¯_ªƒÀ¼{¾Qt–z²Ñ´Ù¸s›z]]ŒƒF[uO_~Z}˜kœš‚Ùg‰¡U€ŸOt”Mo…Iq‹Nl‹Jbq6K]-D^+CQ:Vh8Nu:Nz\\“xx¾™’à—Ž³]ngx›ar†Rq’o{¡h‚¤i†‡e‡†Vx[“UwrGfsYw£i„¯z… cv“`r“bzˆRh{Jh€Tr•Wv€IfiS4J,HH#aR$Ls6Bao‡AS‚VJkGWj:Gu8>c?MW0\Z-Sd3~d?ls6jyRnlL}aB€e9ŒzGo‡WzycguQ\pQ{cI˜o>|N†kXˆiRŠkIfE¦qJ–žbš«vš¯z{³dxy\Qf=¥J•¤]RŒf[N…v>§lÄ£bΠV’ŽnXuZWrYUvBZm9Un9ªX0…e)hyV>mLeO3as:)U,80#^>A|8DUO*U/.)0!FEDV:ŒG'gEpqe„“M¼q_­…v~igzVi{Wr•Cq’UV[b`IM[5FW8MF-–I*¶n/`‘zk_ONL4cB1fpGhi>2Z9c7!\†9‰žOl¨XÓŠ]@âw-;SG;s_&|žSk mdag^Q•Dv¢cišgStYJgjL‰VN¡{J_H“…B|šj–µeA\X2-(2-!HC#®xB¬á¡€”™c?Òå}jЙªÀ`UԄȉS~÷“dÅsY›R[‚BO}:gpByw>TkV/fA;Ï¿uÏâ«dÒ²eK{¹uGoPVq5¡f7{©qWiOé^=¯€Í—syxjškQRJEaD,åIoª‡zT?·xT¥£pw¸LnMxR/zP†E¦§dª©whXi˜L–˜L†£ržU8nl[[B©}Ltâ’ {;QF7f”VPP8WT4yyDo‡Kb—cb‚A™‡A™¢^«·|¨¬y ´x„ž^NjFjx4‚a8rlTf"F['abJ~ƒQw‡c–£Soy6KR1RcAb}Pb“|~Ò¸×ÿÌïÿŽŽ¨am‹u‚¢v†•by¢q{§ry™c~ _vŠ[rrTykFob7`vHaˆRi†YiL]vZv}S~yUr„J`tMaxKhh>[\OBS(@M(VG)lV*[HcAžD8KKCC#it/TœFP|S:o=+Q5A8!OW"FP=‹[4ƒœPmµw¬YxÅzX‹‡CVUX:8ƒd0l‘O`~YbsEnaBfS9^S7XR2mS=”f4\wGHZ\O='cE&Ih1>d=59%gT(’=~´jV—\–y@2€=OHB]z2kˆPa¤ER†[Jg7GM3YG#OL0=U0I`/OW)RdCLZ6wd3 TX¦YZSLJq4AF&NA'sd9U€WPQ>WY>GfNZY/nkHLŠ]^xC\€>z‰D•Sw¦lZlp§zGÇf°¸lŠ”iChM@4:=,„`4qšb}LWRƒWSOAÔœGäï´ÿÄÍñÖÿ¡Õÿ¡‹ä™dÀxWy\gu8N‚1Je*WQ3Kt<¸o:´°·â m•ˆ…`DCqWlr6[„GÕwCrß™eK>‰_C§VMrZw«jixT|pF—€Wã‘n‰¥qNƒc™“`UŸoŠpAšˆN¡wEÓ}\°«…zÔ‚f‹M‘‡GÆs`¸gy‘M¨œ]Û¬vž±wV‰IdY1s”XT€Yfi;hmJpm@q·anža¨šL޹s{sGq~E²ƒFˆ£dy”TdtHFf0Xk&€p3ÕwP‡•dHŽSdl-º³[sqL|~K»dŒŸapfSuL…S*S_>x2M_.|^>ty>€E•O­¿Œ°¦e|¸Vm›IfªWmŽK\u9Q”Kee2Xv3:_+5h8/08K'WlD=tJvpGcsWWk3g±\ų~Éæ­[¨kS‡PLt(t˜OAs@X5"ÔgRuE)¨qŒ™Cß¹}ž^‘­\vÜpIw0~l3±˜p‚F©pO¼¶‰¤jL¯Ÿ[À«sÇ«vÿ®ž´c­ˆi®¯{€„M\`6wgCe^@vrO}Mœ\KweQw}GljC^X:—[E¸×z¨qYˆP†“WmkLedPcP‰¯`x sžÄ^x•^޽x—”e¼d~I™TÊ£\ÇÆp¶ØcޱP¦Éx©Su‹MtJm˜BW‚9[•V‰¨]pPlE}‡Eg{IŽ¢S`w7_b9k‚R…ŒIm}K¯…[Ûrç½…¸zY©`¤°zÆÁ|ž©eÄ¥m¼Àxf“K[i`jIm‚Xw«u©Âwo¢q¯©r””k’œ…ª¹‡›¢i’ŽqÎÓ£ÿêÊùÅŽ¾³b¨x›¦t”«m“¦h‡˜\‚šY}ˆ\‰ƒD]xDbQ|ªh±Íl—Êaƒ¶Od‡:P[1U_E`j_‚‚[ІGrr4EV9]~h°¬ØÿËÝÿŽžÉ_l€Sil£{’«px™^k‹gv–_n‘_uˆV}~Jtq>qp9XkQgXjŠP_‰Ud’Qc€LdnG_xFeK]ƒAVDfzA;F3BL0SC-^Q)}]2`‚HTdR_WDLqX™>[j^g`9nw@K}RP\G;h=:S7ZE0V„Bw‚\z•Jƒ™k‚¥x¢¾p]½|9poA>>UE)pk;suJ_‹RfƒFMfFPJ9nK+ih7sg?„l?ygFMi[bG6HF1VQ-Eg2TZ3‚ˆ8Z§Up‚LS“Df€KVœEr„Q‚s9h˜^pœUHšj3G,(? 586=I‰@Kf1me?]nEq[Ir–JPšOTbC@w4IQ1tk7NzTDkJEG/c/i|P‹xLx¡bq¡nˆ§lZ†Wm^A…N¢w›|g£‘X¬Šh{²a€cUn˜]U…v{a6a›[HmHeƒIj“X§™`´ÊjÛáŠ×ížßÿÄÒÿ¶´ÿ’šÂ‰gÄ‹€rpXŠJMM;]]&buB¢¬Qv{oµ‹T„ˇq|i[u2>T#‰Y5rŒZMi8p„EO–[Wf,Œ¯m•°„boDQy@Fe*Sc0Xn2\m\U8Hb(H;&mF5jvFs¬Zeñp{¢aw|S‹ySŠzR‡r]•‘n­jœOÉ‹bË‘e~cž®ƒæì‘¹Ü¸Âf™ƒZž“a’ŽQ–ŸTŒŠW„’TxqBœW ©}wŠO¨„}­£XkxQ³¶„þ¥ÿæµÍUˆ²ušçsªÄ}±´dzœY¥d²½gz“QbŠNg’Nv—`‹¡Ur›BW†B^@kŠBjˆP¤ŽNu{6ooA‚]q}H™d^Ÿ¡aƒ{aÅš{· h¥¸t•gš_lr>`v>zs:ypGm…Gcx:akT¦¬£ºà³áz‹¢^•¡_‘¤V‰•?iŒ8Vw=]v4Lr4q|?d„Kt†Y‡¯z„¿Œ¡ÆŽ¥³cavFyHI–—Qp†OxœOg†HO`DQwS|™zÓõ¬æÿ¶Úÿ³¾ñ|ƚlj€—d—x݈Úϧÿß®ÿÊ„²Ìºè‹ž¿|˜ÁrŒ¬_ƒªg“¾]œ•Lr‰Mi˜Kc’FhI‚¥f§¿h›ÃZw¬DRfF.NG#Fc,N;,OW'J]1LC)S:&[>%Q_8>a;E82vB$Ÿ{1¤ÒV²ê~¾ò†‘ß‹§¼qÑpN‹i>UDLX0mb)kŒAc“Zb„Mr„L=”N,NML9!Qn(J\9Ze8YuFF†PxqP`VUUWdh;u‰_ŸŽm¦¡ogä`™ŽPuasXBm…AbwU_iSfmCh‚EjtHxo=Œ`FyyBltI€Z;inKLiNVaHZl<_o9†–IX¹d\xTlƒ6g Si­Tn±V9†TF>-\P%„i+6¸f;K?BT"1T6=D.SIOU4[n=Wf&n¦f‡†U—i{Ãgª}syZ’Žf‰v^š±c¤ÓoÅö†Óø§Øè’Áùµ²öާÁ‚åÑt£‹;N?>)_S3²·H\ƒroa:–„Euºw=qKT\'o Rµ€kŸð†Æüˆo¢“|ŠKw‡SaiRxt9ž}Hû©gÃÆ—Ú«y“šz¼ož¤hx²wwŽfk^‰ªerMËU|Š×H>qbeŽWNk=rN)Œ~GžšV°”U’ÏzWe•‰I®k¢šh¢ƒY¦‹Zª€Yk„]g˜OXWQe(ˆ†>Ys={q‘vEŒ‘Rœ’Xo¦`zh@fpB‘›dNl=\N(KI'kq=‰§hf©WO‰WoC.ªsVi’^—Ž]žvH¶X=ÿÆ©ÿì¾ûιÏò½FQ.>D)`A+’eA”V:×”kÔ•^¶Œ[¢ÂmÿêŒÆü¢ÔØ™¾ì›¾³€ßv§|W¦z`†|B}ŽAÍ—hÂ{g¢„g«uTšmL‰sÈhX„­b“}U„wG©„_¼Ï‘˜¬u[q5an;yj?iy@\^8„uAUt@mvNbjFU„BT[4}pQuˆU|zFojolJÙþžèÿœ«©dyOŠtR¼•wÎé’›á|‰–h™bÅ yÁ—w¤›wØížåÿ§¼ý‰œ±a°‹a×r\²¥O¦Ìe¨ˆbS‹K¡¤‡Òÿ•»di®aa…;rmL«žoä˜mïÕ‘™Ä]žµ|¬Ç_¯›lŸ©Sn“E“˜apEm|Y€“Uh3cwCu…Gj…@lAj‡Lw•J“Yµ—Vt†=]|B”]›žP”L‚pJ‹`P®wb‡zXƒ¥`¡`’[_ˆH{™ct­[tUz›Maz9]l?•{{µÒ}ŸÍk|˜N™o¢­\‹¬Uw†=d{9[€3X|VbGUaCrcE|IMQB`S,ZO+QW6OS9`]3td1…i"qR0?o>&68i"R¦¦K¡ÏvžÎ~Äub¢j5gZ!I84*KGh^#Oo:ZSBds=xiAE‘Q0eJ]K&A|4RV?ns5‹žW‰¤jX”jL]_cC8eg8\{PhXL²gH§¡\då£e|‡h\FS`=gI;fc8gnKy_;t|I~|N‰sG[ooïhf@a”Ltc:„ˆZCŽUFU.ßz:†›n¥–|¾ÉsÏÿœm“n:j{@`zK~‰AwW•—X·rZs–t…[rˆP…K¤rWmzgvpKgžN¹S7Š•iUJByS-ozHn…K]JƒŽUkŽdŽ‹M»\‹Ð˜rrKˆ¹jÀƒUµˆj_vZhm;lq1^‚CcpCO†MsŠ7p~Mbf+_f9bb0UV#yh6“v?XnFXm/˜C‰“XU}Oš‰<ÁÿÁÅ󿥇zrƒRA‚P.ptQWu3m›_clIlq8k¡_Ž«r~¯uNk7]t@@€9L_&]b6 Qw‰PtDKg;‚€Izª{‚”Pt„Wa¡YŽHˆ¿‚öƒÊ¨u¾–hel8k…Xcx@ySGn8RQ%yrN@:#TO,‡UÍ„c­€N¬’d»í}“`¾¡eÓ³˜Û“{ƪˆÀ‚k…”jëÈ•ÿµŽøº…«­rÚº­®o߯x·™b»‰ZÖ}XÁ¦€³©k쇖ŠT„{Iz|KY^/„”X¨~VÍ•i~nU£jQ¥”w‹¬o©¬k¶mI¶nTÿÖΈ‡_II'YP,ptBrzNƒcx˜Tbf8kfAi‹Q\rAx‚VŒ’SiU6XL,XM/j{I5;7/=6"_ZC{„N‚«]luKËÔ„†šQm`=eeDlˆRugM¶£„Ýû›»´vœ¡Y½¿_Öª`ó¤yÙûŒÉÿ˜¬àtƒ Uš©[­¥U–¶OªÓkä c’¬]¸”O~yG¡…a‡w[¿¿†x¾V|’Jš–b•¦f’¤]“§\u‡Mw‰Hx—J}Eh€C`~Qb‰B`wEky:Lu0\l8ƒ€J}¦_mKkŽGx‘Bq—J‡¥QDj‰V»Ÿr¶ºt´¢hr†LnŽN—¡VnvFZY;VW.ZiBƒ”]¦µvÏ΀«¿dµ­X_2t|Bšq®Étœ¹OˆŠL…”n“Ã]“§]l>j‹Ca~;b}N‘}T‹…aŸŸf•¨TdFrOwZcŒ\l’WdŠ[ˆšv¥]hŠc~Ž\loAVjs–N€žP{›ZŒZtŒU|„Uk=dtBYjJh~[rƒUrpIlxD`rTdnShjQl€[k“H\{CBh>X€@^s@aoG\teušs|£\k€MY|QUXDb^BOuEicG€d;u|=nmUUfPW\Aj[>l_?irIamTknQp{NqQH~[KZPTP-TM!ZK&\T-n^8}^:ee8y`:ŽuYI&UL%OI/XE.^X/XM4QW3ET2OP0QV*OQ'K]/OU1pY-f1RžS?pd@P5TO-Y_4Uj@7xG&S<80K=NU'OS(PC(pA,iV3FmDD5L%ƒS’¶JŸÓv„ÐrQ™c*cL3<%%P):#B9<[#)?%S*Ot%Q]9Ng/Mz<_{IT‰LplH¥Ÿ]u£|XoqUkJRN@nL/]}?ImO[K7ea9£W8¤‘JpÉ“u`bVeDfL:e[7\lBkZ;nW9rzKs—Xi†V\|Q]”BOtGNZ:Pd;j†Dq˜SnŠ]|žN†ªi‹¸dÀq„¶n¦eiœb7fW:?,tG%cž@Lvl>C&fyK†‚OKaFXR(‚‡K|ŒX_SlL<³{S“d_zO· Wqµ‹ÅŽIŽªsVV8Ic5VU#GW+†{/ToAUp8‡}Ff’oˆb{¦|Dšj€ŒJr­{»sšçŠ~ŸhR…Tgn-g¦Za_;«RÄí½evaeM[œnMd8sZ:ha>}€MqwU_jœyBY{P•œ\š|aX1‡eFqÍ{sY”xD¯¹¼‚ÜPv|FÞyZ~…\šcC>u:PY,CG)XV1z]7âw_ŸŠ]·‡Xµ§kÙ°…¢Õ˦›šjkC¤„cÿ±›ÿ¬‘ò¦“É|Y³­xÔ—jݤ|°j¨ƒF–\¤n[xi?ɺƒ°¢ Ž[¶rN®ŒZ†|`‡U©Ä†¡OåÂ|¿™a±ši¨†`§žjRÓg¬~Už|gÿÀ–zaw€Pel@£`Jר”˜Çlm|AdZ4buLdQlt@~x;uf4^L8OJ1jO>QC+6;3< BD(@L&gd@ÖÀ~jU2’•OWs3“lHˆ²i£ e¯•o˜„k¿Ì‰·¼{‚£^¥Œ[¼˜^¨”_Üê{èç‘Çÿ‡«²a‘ŽK‚‚Iœ«`¥ÊeÁ³`žÃV­®_ÖZË’g¡S™•[ºc—Ñn‡ªTŠ•^{cº–d€x?q‡Oo‹FmŽQZšWu±gk„BPr0a‚7Up4XkAvŽTvC`y@X~6cl5{‘S­¤i¨¦]¿²‰•›dªº…ÒÒ}³šm·ªh’–X©ŠWŽ|Mx~Gj|M€‹dˆœ[Ö­|̶fx—ShˆIb‰F’“]™ª_•¿fŸ«V}¡o¬Ä}ÌÀ}–OlŠKk}9`G‡ŽbЧdž Z†“XqŠ]ƒˆXˆžxŇ®t}²l‰¶hs•cŸf|£Ue’K_~>Qj8Xk>NkDazh”jŽ«ƒ¹ãÁÐÿ•—ªx¤Ä–·¼u†BZq?hˆO`p?_[R„†d™±i‚°g…´f§ÊiŸÑrŸÓv½q”Îk—¿^Ž¿jšÊfƒ¾z˜Ï£±é•›íš½ù‚¥×]u™Ae}[iCNs?WgGIeBAS>AU5GG$XBJU)WS5`T1]S2I0žl5oŒUSvdC^D>T.AL,?@*KB,Q\/]]9ik5Rm??^EBT3]M-`].Uh5jq<€~9bJg{YuzIƒ„O†Yr‹ZDa0dV&>&2(>8IS$XS'mS.ga4Kh;0T/GK6‘W'ާIs´t9zc;DC0F"6N"6L$f‰MZkR^[4LpATA3œZ2™„@y®‹^n^eVKolLbŒQ€fFƒž\ŠŸo†¨d¨¶r®Ýs~Õ{U”a\†W‡Fƒœiv¤r|¬tžmgtX€|I{Š^Z{VXZ@7T76<1@B iW4v‡AC•e^4?l6\_+ve/ºxEu»dZtVrF[wM]{L:tH68(oA#o€Kra§`\fœZM–uYlNrzMQ˜eXmGJj6cg:Mk7PS5Pl7^b;T^FTg\q2F6(|˜AiV@žzXɈg{eZ];Ÿ‚D_—nŠ—RLgHCl-Jb5IW5Rb/Th3^™_\Oc~Eãÿ˜L~-jƒ8r•W®j±ÅŒ­Æ”¦¥†–š[œaÆl™É¶ÊvŸ•]¶Äi޾N—½^«Òf•¥exJ›®e¤Âi‚•Iª§a¡ iŸ«_±©eâqŽ”M†”L¢P©¥eŒNm}S~„P‹„DMs.Yw:[t7[ƒC}KgˆBbj4Rc,^p4VyMrŽYp—Qdj3wˆ\w HMs2qyJ‡¤S… `³º†ˆŸNžwîØ~»£cÜ¡[µŸd³”e†^ŠU“‰_¹w¦X{Wµq…£Uc}E…˜A^†Cƒ¤p«Ö†¨®\€•s²Á÷¿•ľr„“Xes9ZwE|W‰fˆ§Qs„K—t¸ªm”§l™š`‡ƒW€…RŠz]šc£j~§eiŒF[}>S`:Ta8X`Ce~Qf{RMlSŠœÆÄw}a–¶a|˜Jaƒ7RWw¤bgzRƒ˜gоƒ¡ìœ¹ÿ—®èn¬»a™ÄmÍp—¼dºj“´Q€œYލa‘º‚¢À¼æÿ×ïÿ«ÅÂe~~K]pB\o8Ui9_i>b_Apt:Ra7_nA]xHp}Uu‚R]sQ\€\m˜^s™jx—iwbw}KaxPh}TioG^i^}Gh‘Qe—G\{GsH1Sk@Cg]DJIGQ5dX3bb1bp>sm;c~CQuRL\BVZ8bb:OgAUYC[c>LuH0gE4C)89:HR?'YN%HX/vF4rw1j€IW`PZYAYi8Oa:PZ;^M4ge7w~?q~H[UIkVAY=ZG'x\,vy4fƒOYrFOZ;ZS4dX4|b;‡pAf‹KK€Z0fK&K2$+A*GMFT(`G NR&CX/EO%Sd-}r9byGHx\0S968'E;DR"4^6?;5U$4R"4W(G\*Rm9Qp?„s?бT†µt‰©nG˜s3`hHD4Pg,Qh2uU2‚n7`‰X\^Ph]1VnJYA5M[6ŸB2œ‡Ed›ˆˆ]O«‚CtžV¡}Yª¾h’»ƒ…¯|£«bo¶vLugj`>sz8k†Oxari•mZ¤rV~cb‘X“ŠN?­fGNB<],Gc8Il9lzDƒ˜P_§nPkPXe1@^5F@*nH f/lyJf‚PZsPftN=yM_P3Zk:}xOua^¥hr_KgŽDY”„m’Pe‹\6yLaB'^s0]†5U`@t†=G|PMT4Xb4b€Dg‘\vŠS´‚QhÍ{HCn\DUI…t.˵Y¿É„Òý‰¹õ–ÊÐ×þŠ¹Ùžs£‚˜[ ÂrÇvZrYQp8zn@;ŒK>U)AJuj.j€TgT@lS6`k?€nCÿ qÉ÷Ï™ÿÜ’ŒkŠXe^H]R>be:g‚Bd\J‰I.ZUFie0nd8‘€T_hLw¡Llp=]T7ZP1Z?)às.l‰{’aEX86¯U0§§wN‹amf4]m:OvllU’[B±œuÝ™°Ö‰’MŽ•\®·rĤtÿ‹œº]jDu]BrfDg`7yK4iu4z‚P[œP¦oHkžOcxDo†Hž’hŽÀ{›ÂwÄŸ^k–Aˆ¢`“Ç}žŽ`…pJh6w_9˜k~°U“¦kÎß§qÎWye= ›} Ë€©Ão‘ŸN•˜^ɼ†ÄÇh|‹Ng{Fv S£t]¦”fft:_{>]„?ƒwN\w>frB`xB]…9Uw6n…He¡[^MrzTx‡^kGa~H ´zx˜CV„C‘’W«|Õ±x¥£_zbŸÆx¨Æs› T´—`ݲxòŸ~Ê¢cÀ¨g¦¥|ª¹`‚…R‚mU‰ŸW`™Bh}DgH r¥½| «rœ°|š±e§‘g¦“RwzEht4b}=z}_«ªs’¯Sl‡QŽf¢ŸiŒ[t‡Ii†K`iATfIsŠW€a“Ÿl{EYn?Ql?^|I\SlŽg²|x’Seˆ`~­{¡ß€Çe~“Jc€Ak‰q–°i‰¤p¨á–Äü¨âü–ØÒowZq5^oAf@PU9cL:L4H? 2M!24078!DH$]Q(`h+br:]rIehEog;mq<_zIcn?ls:”…Kr‡NYx]C]L;R?UK'_P%b].Lg?KL3UI*M`-QT1O_4nW3\d,MoJDeD5fC6J+ID$DY1iS)§f/z·X†œ|¥Xu}\‹T‚¥d}›]}”`gœej‡Yc’XX}Ql}CwˆEZ…]GjSWh=[d?peC{†OŠ…^Rœd^ˆUo“G`•VUpFMVJ’TCW;IR/2=%+6 -.s4–u3WvOLG;c_1ZzJi’A—UjŸdz\]zm~L””i‡ŸNw]¦d‡b”žj‘§a••jœ“^ž“e¯‰Pi~CjoBPrNkžgf§Y\…Pd\išo·w—«t•½‘¾ìªÇàŒ¤®^p{E[rKw~ŸÈyœÕ”½é­Öô‚¦´PZd:@`:7V8F^Gtœ^®YoŸLiU„¢Qly<_yPz“o—¿„ÄÓl‘®Se†Db{:Yr6Qm9\]:\Q6[K;RWDUxNs‹_}tOenRnˆ]‚ZzŒR_~YpxWgydo¥„„È~€µgk—jp—]m~E]q@`kGgw;\‚@YŠPp—as§h„£UcK$klAebQYRG[_>viPal@ZkN[Z>Ih>VL=UM0MV1RO1aT,f6_FT‰tOdR>^9OE,AY+KA2W@)TW-Qc7Zb:ko5Tw=JiBU^<`a3\x;nrW}|N}P_uWNgK6[;KG9ZB(DJ*9H-KA'MH!ZG(kJ-Wh8J_68X8RP,^Q$Ub7FmCCeC9J07B1DI.HE*PY+Vy<[v>Ta6?zAQf7Fb8ET9i\0Wƒt0U*LG ˆq*:€KyP0¸wDKiVX1]tLUa;P@3UU1ˆL/iªNSpTRp@”Y0÷·Z¼ÿžžÇ„¥jr–`¢¸V‡×~d›P«¸Pß‹L{[Jc$dp0tp9FZQo4klCqQ:ÿH«…|W^RS;R€Uw[/_n)Y‰C\Z(Yv/‰[GΠo™[O»«}iS~€j—†l‚‹iŽŽS° u¾Œl…—e¤q@®‹sÆ‘f»ƒ±†k•y\iˆ\kT>´tSg˜q_n8niD€‚XrZ‰q9q`3rE|v?ˆ„Gr…^šsQ„tR• U…{>qt:¸qP­‚cå…kÖ™d¶¢t³žxµÒ•ϧ•¨ºv¯ªtÈ^µ„hír¾‘b’œd’}C¦a•¼hsPwªV¤˜f˜yOº‹i²É‚Ïâžµò—¬êŒ§°i³vP‡•Zž…\TGÚ”„g€H~}GgpG¶qYÍwdˆtöÝ©~µx‰cŠ~]|šm¬kä¥ŽŠ‹f»ÒÿÙÍåð§}A~vV©¾ƒ¤°‚Š¡€Œ½Š{ªzg¦^rzJ’rNZ|Aÿ²Ú¢ÿºw³[‡°YˆG¡‘Q•¡QuLgn=ge?k~D™„RËc‚¨ZŽ«qÐè§“µ\‚£_zGV^0On7ŽY˜š^ºp”È[ƒ¸[‚µi|˜KwnDµŽpµ s¢®i„“WjOv|TˆŒe­Ø­ØÿʶáltŒF…¤]T”QON\ž\UxKSm3OnJ‹–X¾¨m„¬`ƒ‘L†¦e‚†T£Œiºt±©z•¬Sr„VÚ­‰È¹{̦m¸»ƒºàÀ¨gšÂZ`q8tNs‹Gq–Vi›NZ{:Ru7Op;h{R„‘s¬¿…ÆÀr™†S}u>rHm„Es|P}ˆYzX‚˜[†–WtŒR†}j™ŽX…S¡šUƒ‡AŒ„Ao›cu§d{ŸjŸhŸaƒ˜a~gŽ®st˜Z{š`¤l¥Äލ¼v‡¥j}š_o—aƒ®‚›·|°à¡½Þ‚¬Èg~›\vwdŠn|‰ÎˆˆÎ~޽t‚¹rš¼§Ð…ˆÉkm¦Wƒ°S©`‹—UiˆF`}?Z|EXvR\=UtEopCqlPŒ…Zž€HimMp©v›Õžºá”¸mxž‹°`mGarDafC_tF]†I`QmždtžXl}P\^$We9JGFXCGiT6ŠvIvhTemOUxNBmPRDBI?)VF,QW*k^- c.c¬LKB^YSO1]K'OR.XZ5dT._X+NV9RC.PU7R_3U_8me9qp>zNfUV^SPPBRP1EY*P_0J`0RC04;*42(KAjAcO%Td3R\FJ/ES5S]2Mi4Rf7]g'xp;”Hº±\ˆÀ}ƒ]—mF˜T’°t”¾t°½tŽ»q‹™s™Ÿhr«tM}cNPB_`)Tt1[m:OoDgpIRyHM~LLrMeX/E]?WR7db-Ym9^X4jd4e L`‡UQ…M_oKa]?:v=;606T+6+2,$2)u@•rBjs8^kCSsB{vBg‘mhRN>vML@4_V.2}CRF%d(E¨a:W;Q] ™k+Ux\Ni2¦v9Z”LSgIae.8rFCC-TJ(X*b–Jeu]T—MuKÑ _“Ãy}¦ox”M~…Kš~Iu~W£CªÑDƒh;Q(BS&`P(Ms=jT:…\9S«YE[=vl(]ŒR•?5QtQlr)btBuj>ÿÂ\–ÿÛSt‚i†AbYNl€?bpERd>smFfgDLRFTX6gO-plIp[AU–U]V2\L.±V8‘Œt]µi†SƒƒO?O:T6$›Y9vš[QrC[b,§B*TePˆk(h|FQ€Azn2WrIHcŒ^T…dj7y‹Qg]?…‘V]vT[qJOzAl©fA™hjM,deP`|R”lExžodHI§}ZmA6<&U@U{.a\3a„Q[\Btc?;7(Ša>gaKjnKµ„UÿÓ¢ÿ¸³¨s_j9noY­zZ¡gR–|WrImq_naT}m8ŠpV]”ZmvP„‚OxxB{}Qel9kuCgEjs2vk7€‡VŠ|Hw˜Zs…8xu9£˜[¦m@©xEædàƒz¦¢†µ‘xσo¾‡tÖ–}ꣀãvä’}ÿ‚••jgmT‹W—ªci¢H—‚K„–R}R´§qÀÜ”ÆfŒ¢Ll›S…tJ„V”n?„MŽm=x™RkƒG„‰TwoO˜b¨|c”r¦É³¾æÔqÈ[nz›t²½´ÿ­×¹ö÷ÌüàºÿÛ˜sŠGld‚º—‡µ‘ µ¥š¦„~o]˜qLˆa@ksGã·±ÿÿÿ¨¶vˆ¨czšKzM“…P‚Y•²`ƒ¨PŒtKw>ŽƒJzEjoB›n[©ªk†—V–QksCt‚T¡h¶»h|…P}ªM¿\‚ÀWn…BlhEªuM•d~ŠHsf?wIª~WpyJ£’ŠÕÿ¡”Â_bŸEooU´Æœ½ÿÏÞÿç¸ÿ¥Y}A_…Tˆ“hˆ³b©£dt@¥°‚›£h§ŽyÚ“h„K”R„U¸“jÑ»i¨°o†«k¸Âz‘·oœ¹onwBt‚R{šK{¢a‹«`€˜bc“Kk€Wº¤f‘Ÿn»`Ÿ—jœ–`„KjIfˆK—cŽ¥_†£_s€JxwOx€aš¥x¢°pŽ¢U{ŠA\}9_ƒW‰šŽ¨½amŽVnˆLSp9N_?KhMŽtˆµƒ´Ó‰•²j‘Á™¤Ü’°‰««l…™n‘¬g~žf“œ\|Npvsž°u”¡Uzešµ£Ä쫶ᘞǕ«Ùƒ™¹‚˜¹™¢Çˆ‘Äbw¤Lv“PhuLa„N\~GUu.;I:GdBUoKt‹Ots=R\[rR|OGZ}@@wTALCLE/uM-kb0io<¨l9]«RJ¦GR^NC-gO&uO,j_4cc8Oa2EH.PD*PH*\K/oa3ˆxGŠmJkˆX?c_=BC48%G4 UG!`l1Sr<@hE265/,4=B?i1`Y)LnBZR9VW0Rc1OmGSj;Na*YQ6}e5|”LŸ¯l•ɃfÀŠSŽk:mC@B%DP*?R+/[$)<*19=;Hx¦ci¢qKˆnM]GM]8OL+Qo;Gv@Ql=P#~Vr¤Kt’W³¯W¡÷ŸUk€£ƒCfŠrV•WZ‹Jp}Ws“aeŽ]g\QBeCVN/VvLUy)Ut5Sh=Zq+W{>h‹TaˆTX€I—|2OždIi<†R5W®cNƒO@Y4‹Ku¥€cŠT]y9PU6Ÿ†X¨aZuáµz}\uvPŠb}¨m{xT{¸‚;g@lk8{d;{l>pˆR`W@jk>j}ImpHwX>~iF€žSÿ…~£•{‚oYÁlUriY[gLØcM‚—y††\|€l huP]8_T/…†Av \…´aŽÂk±Ó‚†R“ª{˜ÜŽcºtt†LY}Q™jVµ¥ˆz¬s|¤e³‡YpxLgU4g[;ˆwJ¡Ñ…xˆ\ˆtU€}J•pE×…dÂm§lsTsxPmrDcpD~”Re‰?k6€…Iˈjïÿ¼Öÿ¸‚¿m_•?–a¼xZºu\’§l¥Ýxaˆ@hwGv…J¥‹e³ƒg´‰oƒuCl|N‘”|£µ ›Ö³¢ÂŸ“¬Œˆ¤h„†HÍ xÁºeÿ»‹˜„GrwL‹£|£À’¦Š…£{T\;Ih8OM1g@-bC6`ˆH²™ƒÿÿÿš«c¤‚`“€S²X¤œSxIyiE‰ˆS“vJxH‹T`ŒE`gQO@oZ7by?ZoR\XFeP7nT5V^5bW7ž_4V¬X4Œ›CKYLC!WK"U?#HC,ZL2j\._Y2S^BPT?]L7sJ6ld?ikK[_EGF;1=267$G7!qK"n,`vGFtR:^F.>)78:E@C d7$QG(TR0SX/qW4eh:FsM>l=JQ0rG' u4ŸÁr‡Ð—c¬ˆQx_&?\)4P$.=%K@*BV*6E.)B"82L;HP*Fi3NT+ic,aƒ§]i’b|qMmnLTuJXeag8fi=cJ`ii‡]Y‘fKrSBoHHI4KQ.@hC=\6Ld-Pi3@e5O]1Ah8LbDQu58^E>N%;@$A:$5'<@!:A(8E,UR*S\.uz=V‚G;R/8O,^Q)OŒFBm:8U$?DVQyj*„’R½äsJ¡ŸgV+ggDJnA~U(ŒsR‘r_‚mUw…^{}Zy|Z}cˆƒeyzo“q_nŸ`IK5LG#tQ.lbLmC{lJ…¢]uv\IF@Ya.Kd'][%Xn;Zu:Vg*n|Fdg@ll=ˆqCXtK]‚]L(–R?dpP¾ƒWzÈ«m wT‰Y‹”Wg¤€Ç–dL¨Nc;…g6‚z?ŠlLoiPqT=c‚MzO>x~JreC…JdD=«jV{ZLÿí¹ieQ[uBé‡dºšvqƒnðˆb°‡o‰­es¢F€’LojE™ˆUlQj†UÎ{PZs=Vf3‚l@†d_†[Š…C€\‰œ_|mE¤‰[žz\ŒWx{[csV‘†[”³{³‹n²žl i¥‡]Œ”`½©o¼é›ƒ¹q®Œ[‹‘l~}Rn{<_f9^r*›€Dʬr×àš›Ç}ru?zS~~Mœ|R·£_·V¯¤u‘ŒI™ÃZ‘}`œ}S…fO«Ša{‹Xo“[„˜k§µŒ¶Í ¬ÄœŽ£ta§S^—?‡¦g”Ç`È«`—±Z‡©n¢¿fAC#8+N-%RB/a];aI6RV:`[?± q¿Ëÿõä“ÐmŸ’Q›§IŒ”J©†Lu„?vCXyHq¬fzL—ª|—í†h‰Bi’HmxL²†`¨¦d¢¬g¥˜h™ _™˜cW‰ˆS”¦b½Ïu»Y‘˜f†\gp?iU=pQBvƒ[zGˆyBq~=Uf4dnLÀÄ•¶Û”ÁùÆÈÿ¿¿Ý}ŠZ~tY¥p ˜„{¡Y}vL|„JŠ¢g„Œ\ˆsS”vXwxG}‡Yq“UivImwLj~Y‹Wˆžo{œbœ©j›Yv—Fp\•–iŒ¥[^~FxoS~RhLr–S£°s¢‘a “^Œhª¢m¬{—Ä‚™¯€Ê¨{Ž“m““mš›X”Qk„Nni\‡ˆhЍg|ŠRewAc}Prj†™by˜Y`€Ka~WpŽaŒŒRg€CcyDk}W€€c}³x€À€…±lm“Z`|]y‚SwZ„®b~¤jŽe¡¢fˆ“dš£o‘_jcEGUCh‚LS~XaŠJU]7YX5SiK~gy™ZpŽNjUqžUwŒZ†¢iq‘KRW,?9+8D/EL6ZP8V_?`qD[~BSpDRlIHjUY‘oy³XdERybt›c|›MgŽJl˜^‡¥`yŽOkzAUs@EmGPwNd†VB_&j[9_s9[sHDpEMW=eH+il3ng;ZxKOTP>J:EH)G>*ZG(T+c™IM„“DbX?N0XL,SU"\U6hZ4oh;llCc`K]]Fg[6Šg?‘…SSnXAIJ67+:-K4!QH$aY'nh8VnCLaK5dB0D057AHCE=C*D=+NH'HJ0b^7\p1Nw>Gx=DlA`S/¬t1šÉbs¿WštL‚a?oS6N881,G@B\+N]4eS(Sh>AUD:F,9G'@K&UD'?_6>G6M[&^g.Pu5@]8TC';I*AOCOV-ed8dn=S{NUZMZc8ixMƒCm˜_…‚X‹¢[oŠgh`qH}rC†NcVlpRll=Ug>eo;reO~KE;=H*L>#ZB#gX1Ow@QoBk0™~N=‡N;>.AU.BK4JR(Lb4T`=Rj8\|3P‚@[d8Pc-KU0Pv.o{Iš¬`Cqrb4b¥WmtN…t@“œX\Áyx‰YЬQe©qT‡G;]:3I#^YMd.r™7tvIO—L.I6=18G 51!:46(W[`j4I›QX`:;u6Nd.Ti%Ha#/Y9BMQjn2‹”GÿÙgZ¯Èkg4Y€TL\>gQ3zc;pR=lU?ieABZ=eR#Xi?hS5DL6}h;xoQW¹`AG3:%j_:•ˆJŸº|wœw„uQmZN^EOk>Id/EV"?Y$8S"{Y&<=EX/Ti>bpAV?]‘NNkDKL)h=+ŸuJ®ÒŠªV„¶gmÀ„a³uf¬f¡^l‰\_ˆj‹rL¨³„x®‚ƒ·ru”e°‘h\ê¥}kMŠÀgˆ—U kR‘…fÁˆhdr^ku<†xQox3nsS¤wbdTKÜpZ¨’†£‰uvf7Ê]JœmX]zZŽZ3p‚?Pi.g®nwsGpR§ƒWlµ|^˜Zˆv>Tj6n}CQw@^dAhŒ^[q=‚‘SxoImsG¦zH¶»Œ›Žf’s[¶•x½¦vƒ€[­yLŸmT“jÚn»tKµvWÀÄ’®lƒ©_—«TŸ—XeŽGWo:Tr&›;—¯P¦š]jmJxxK…tFrrPp|Aˆo<„_Dnc>_W;oV:‰_6hM9½‡Z…uCjI9uW‘~j¢Î¶¥œ—tViD€_Ii:4kN¤›]³Ë{ã¦h|ŽO‚’L;“GEŒO[Y^§dMoE]pPyŸp…ÍxzV –cÿdz«Æ~¤c£f…—S¦–[{~M€‚WªÎ{ÁË„^wG›‘z´c€£LÆú´ÿtŸI‹ŒP§¦]ŒˆO¢²o½žq´£n³¥b‹¡\}¯U–®b¡Ž\‡mHw†V¦¬pªp¢«f{…?s}=]Q>ŠmC_vBˆe®Ô™ÎÿÑìÿÌ—Õt—ʆ“¯mo†U¥ˆnĆgbv:luC¤·k‚ÈosOUsQdmP¤{iǵm‰ƒk¨d‡LyPŽ­x‰½sƒ¬i‚–[€ˆN}„U{…ašÎg¥Qn…Bg~L‰¡[„Q…†b¥‹c®”g¿¢Üò¬»îªÝ‹˜¬l°–qq Šc£žQƒ‘bˆ“^‰ŒpŸ ax“RZPZ„IVVr–io™ih–T_\h™^cŒFVCw\ŒM€‰Oy’† íϼﬖÄz„£jªy~›`o”d„©s›·‚«¬uˆŽY€„P™¡g”¥Xˆ›\ƒ¡mk™wv±fh?8f12^12b=EeNi}?Vf?g†SzŸHq”KeŒ]n†FO[@ESAIlAQ[:ghOnœooÀ€‚ºka–Yc’ea‘¦á®Áï‚­HO}Sl\t‹?cr>i†H^wB[yCMn>QwOZ…Jd}Le{B;b0OQ>TV4W[5K`?PV7cK0`j2lh>EwMQ/FU"OW%^`1bf?XpDWKRzCiF+>C+8M*J3 JR(@]D_`,W~-Rl5=r8ZS+bi4FgQEJ8K^-^N,Ai4R[B[\/foGk‡Ca„F£w=ˆ Lv¢}k†ZW|RfxM@nNYC>og2Tƒ?X^?Vb2XO8YJ6Jk;=K4Q<,`P,_~DPkQSK.=I8OJ&FV:PL-k`3YZ2vi7c{ALe@Pq9YwBWqNž…6¥®lQÁ’GXYNP)`T6fX=QwJ`{W„w9ƒ«bl®so’\6vH9A&